/*
Copyright (C) 2011 Brandon Chang (mingzhez@usc.edu)

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */

#import "AppController.h"
#import <unistd.h>
#import <string.h>
#import <stdlib.h>

USERCONFIG              g_UserConfig;
enum
{
    GOAL_NONE,
    GOAL_LOGIN,
    GOAL_RELOGIN,
    GOAL_LOGOUT
};

enum
{
    DELAY_RETRY_NONE,
    DELAY_RETRY_DOT1X,
    DELAY_RETRY_TUNET
};

INT                 g_Goal = GOAL_NONE;
INT                 g_DelayRetry = DELAY_RETRY_NONE;

int mytunetsvc_login()
{
	
    if(g_Goal == GOAL_LOGIN)
    {
        g_Goal = GOAL_RELOGIN;
        g_DelayRetry = DELAY_RETRY_NONE;
    }
    else
        g_Goal = GOAL_LOGIN;
	
	
    return OK;
}

int mytunetsvc_logout()
{
    //os_lock_lock(g_GoalLock);
	
    g_Goal = GOAL_LOGOUT;
	
    //os_lock_unlock(g_GoalLock);
	
    return OK;
}





VOID mytunetsvc_transmit_log_posix(LOG *log)
{
#ifdef _POSIX
	//...
/*	if(strcmp(log->tag, "MYTUNETSVC_LIMITATION") != 0
	   && strcmp(log->tag, "MYTUNETSVC_STATE") != 0 ){
		printf("mytunet: %s %s \n", log->tag, log->str);
	
	}*/
	
#endif
}

VOID mytunetsvc_transmit_log_qt(LOG *log)
{
#ifdef _POSIX
	//...
	if(strcmp(log->tag, "MYTUNETSVC_LIMITATION") != 0
	   && strcmp(log->tag, "MYTUNETSVC_STATE") != 0 )
		printf("mytunet: %s %s \n", log->tag, log->str);
	
#endif
}
extern VOID mytunetsvc_transmit_log_qt(LOG *log);
#ifdef _WIN32
VOID mytunetsvc_transmit_log_qt(LOG *log){}
#endif

typedef VOID (  *MYTUNETSVC_TRANSMIT_FUNC)(LOG *log);

static INT mytunetsvc_stop_flag = 0;
MYTUNETSVC_TRANSMIT_FUNC mytunetsvc_transmit_log = mytunetsvc_transmit_log_posix;

void mytunetsvc_set_stop_flag()
{
    mytunetsvc_stop_flag = 1;
}

void mytunetsvc_clear_stop_flag()
{
    mytunetsvc_stop_flag = 0;
}


INT EncodePasswordByUsername(CHAR *username, CHAR *passwordmd5, CHAR *encoded)
{
    BYTE md5[16];
    des3_context ctx3;
    BYTE output[16];
    BYTE pwdmd5[16];
	
    CHAR vn[200];
	
#ifdef _WIN32
	DWORD sn;
	GetVolumeInformation("C:\\", vn, sizeof(vn), &sn, NULL, NULL, NULL, 0);
	snprintf(vn, sizeof(vn), "%s%x", username, sn);
#else
	snprintf(vn, sizeof(vn), "%s", username);
#endif
	
    //MD5Buffer(username, strlen(username), md5);
    MD5Buffer(vn, strlen(vn), md5);
	
    hex2buf(passwordmd5, pwdmd5, NULL);
	
    des3_set_3keys( &ctx3, md5, md5 + 8, md5);
    des3_encrypt( &ctx3, (BYTE *)pwdmd5, output);
	
    des3_set_3keys( &ctx3, md5, md5 + 8, md5);
    des3_encrypt( &ctx3, (BYTE *)pwdmd5 + 8, output + 8);
	
    buf2hex(output, 16, encoded);
	
    return OK;
}


INT DecodePasswordByUsername(CHAR *username, CHAR *encodedstr, CHAR *decoded)
{
    BYTE md5[16];
    des3_context ctx3;
    BYTE output[16];
    BYTE encoded[16];
	
    CHAR vn[200];
	
#ifdef _WIN32
	DWORD sn;
	GetVolumeInformation("C:\\", vn, sizeof(vn), &sn, NULL, NULL, NULL, 0);
	snprintf(vn, sizeof(vn), "%s%x", username, sn);
#else
	snprintf(vn, sizeof(vn), "%s", username);
#endif
	
    //MD5Buffer(username, strlen(username), md5);
    MD5Buffer(vn, strlen(vn), md5);
	
	
    hex2buf(encodedstr, encoded, NULL);
	
    des3_set_3keys( &ctx3, md5, md5 + 8, md5);
    des3_decrypt( &ctx3, (BYTE *)encoded, output);
	
    des3_set_3keys( &ctx3, md5, md5 + 8, md5);
    des3_decrypt( &ctx3, (BYTE *)encoded + 8, output + 8);
	
    buf2hex(output, 16, decoded);
	
    return OK;
}

INT WINAPI mytunetsvc_set_global_config_from(USERCONFIG *uc)
{
    memcpy(&g_UserConfig, uc, sizeof(USERCONFIG));
    return 0;
}


void mytunetsvc_init()
{
    mytunet_init();
}

void mytunetsvc_cleanup()
{
    mytunet_cleanup();
}


@implementation AppController
+(void)initialize{
	
	NSArray *objects=[NSArray arrayWithObjects:@"",@"",@"en0",@"0",@"0",@"",@"",@"en0",@"0",@"0",@"0",@"",nil];
	NSArray *keys=[NSArray arrayWithObjects:ACCOUNT1_NAME,ACCOUNT1_PASSWORD,ACCOUNT1_ADAPTER,
				   ACCOUNT1_LIMITATION,ACCOUNT1_USEDOT1X,ACCOUNT2_NAME,ACCOUNT2_PASSWORD,ACCOUNT2_ADAPTER,
				   ACCOUNT2_LIMITATION,ACCOUNT2_USEDOT1X,ACCOUNT_CHOICE,REMOTE_PASSWORD,nil];
	NSMutableDictionary *defaultValues= [NSMutableDictionary dictionaryWithObjects:objects
																		   forKeys:keys];
	[[NSUserDefaults standardUserDefaults] registerDefaults:defaultValues];
}
-(id)init{
	if (![super init]) {
		exit(1);
	}
	[GrowlApplicationBridge setGrowlDelegate:self];
	consoleCount=0;
	mainConnect = [[NSThread alloc] init];
	remoteService = [[NSThread alloc] init];
	remoteControl = [[NSThread alloc] init];
	NSNotificationCenter *nc= [NSNotificationCenter defaultCenter];
	[nc addObserver:self 
		   selector:@selector(connectionDidEnd:) 
			   name:@"connectionDidEnd" 
			 object:nil];
	[nc addObserver:self
		   selector:@selector(cleanUpService)
			   name:@"remoteControlFailed"
			 object:nil];
	[nc addObserver:self
		   selector:@selector(cleanUpService)
			   name:@"remoteControlDidEnd"
			 object:nil];
	[nc addObserver:self
		   selector:@selector(connect:)
			   name:@"connectCallByRemote"
			 object:nil];
	statusTitle=0;
	money=[[NSString alloc] initWithString:@""];
	networkInterfaces=(NSArray *)SCNetworkInterfaceCopyAll();
	consoleLock=[[NSLock alloc] init];
	NSBundle *mainBundle = [NSBundle mainBundle];
	NSString *path_0= [mainBundle pathForResource:@"menu_0" ofType:@"png"];
	NSString *path_= [mainBundle pathForResource:@"menu_" ofType:@"png"];
	NSString *connectedPath= [mainBundle pathForResource:@"green" ofType:@"tif"];
	NSString *disconnectedPath =[mainBundle pathForResource:@"red" ofType:@"tif"];
	NSString *connectingPath = [mainBundle pathForResource:@"yellow" ofType:@"tif"];
	image_0=[[NSImage alloc] initWithContentsOfFile:path_0];
	image_=[[NSImage alloc] initWithContentsOfFile:path_];
	connectedImage = [[NSImage alloc] initWithContentsOfFile:connectedPath];
	disconnectedImage =[[NSImage alloc] initWithContentsOfFile:disconnectedPath];
	connectingImage =[[NSImage alloc] initWithContentsOfFile:connectingPath];
	emptyString= [[mainBundle localizedStringForKey:EMPTY_STRING 
											  value:@"" 
											  table:nil] retain];
	condition=[[NSCondition alloc] init];
	flagLock=[[NSLock alloc] init];
	quitChoice=NO;
	connectJustPressed=NO;
	stopService=NO;
	signal(SIGPIPE,SIG_IGN);
	int portBuf=[[NSUserDefaults standardUserDefaults] integerForKey:REMOTE_PORT_USER];
	if (portBuf<=5000||portBuf>65535) {
		portNumber=REMOTE_PORT;
	}else {
		portNumber=portBuf;
	}
	remotePortNumber=REMOTE_PORT;
	return self;
}
-(void)dealloc{
	[flagLock release];
	[condition release];
	[remoteControl release];
	[remoteService release];
	[mainConnect release];
	[money release];
	[image_0 release];
	[image_ release];
	[connectedImage release];
	[disconnectedImage release];
	[connectingImage release];
	[networkInterfaces release];
	[emptyString release];
	NSLog(@"Abort.\n");
	NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
	[nc removeObserver:self];
	[super dealloc];
}
- (NSDictionary *) registrationDictionaryForGrowl { 
    NSArray *array = [NSArray arrayWithObjects:@"connected", nil]; 
    NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:
                          [NSNumber numberWithInt:1], 
                          @"TicketVersion", 
                          array, 
                          @"AllNotifications", 
                          array, 
                          @"DefaultNotifications", 
                          nil];
    return dict;
}
-(void) growlAlert:(NSString *)message title:(NSString *)title{
    [GrowlApplicationBridge notifyWithTitle:title
								description:message
						   notificationName:@"connected"
								   iconData:nil 
								   priority:0
								   isSticky:NO
							   clickContext:nil];
}
-(void)awakeFromNib{
	int i;
	NSUserDefaults *defaults=[NSUserDefaults standardUserDefaults];
	NSBundle *mainBundle=[NSBundle mainBundle];
	NSString *path_1= [mainBundle pathForResource:@"menu_1" ofType:@"png"];
	image_1=[[NSImage alloc] initWithContentsOfFile:path_1];
	
	[statusMenu setAutoenablesItems:NO];
	statusItem = [[[NSStatusBar systemStatusBar] statusItemWithLength:NSVariableStatusItemLength] retain];
	[statusItem setMenu:statusMenu];
	[statusItem setImage:image_];
	[statusItem setAlternateImage:image_1];
	[statusItem setHighlightMode:YES];
	NSMenu *interfaceMenu = [interfaces menu];
	for(i=0;i<[networkInterfaces count];i++){
		NSString *string=[[NSString alloc ]initWithFormat:@"%@ (%@)",
						  (NSString *)SCNetworkInterfaceGetLocalizedDisplayName((SCNetworkInterfaceRef)[networkInterfaces objectAtIndex:i]),
						  (NSString *)SCNetworkInterfaceGetBSDName((SCNetworkInterfaceRef)[networkInterfaces objectAtIndex:i])];
		NSMenuItem *item = [[NSMenuItem alloc] initWithTitle:string
														   action:nil 
													keyEquivalent:@""];
		[item setTag:i];
		[interfaceMenu addItem:item];
		[string release];
		[item release];
	}
	
	[connectionStatus performSelectorOnMainThread:@selector(setImage:) 
									   withObject:disconnectedImage
									waitUntilDone:YES];
	[self setSaveButtonEnabled:NO];
	[self performSelectorOnMainThread:@selector(setConnectItemEnabled:) 
						   withObject:[NSNumber numberWithInt:1] 
						waitUntilDone:YES];
	NSToolbar *toolbar = [[NSToolbar alloc] initWithIdentifier:@"Main Toolbar"];
	
    [toolbar setAllowsUserCustomization:NO];
    [toolbar setAutosavesConfiguration:NO];
    [toolbar setDisplayMode:NSToolbarDisplayModeIconAndLabel];
	
    [toolbar setDelegate:self];
	
    [mainWindow setToolbar:toolbar];
	[toolbar setSelectedItemIdentifier:@"Account 1"];
	[mainWindow setShowsToolbarButton:NO];
    [toolbar release];
	if ([[defaults objectForKey:ACCOUNT_CHOICE] isEqual:@"0"]) {
		[self performSelectorOnMainThread:@selector(setAccountStatus:) 
							   withObject:[NSNumber numberWithInt:4]
							waitUntilDone:YES];
	}else {
		[self performSelectorOnMainThread:@selector(setAccountStatus:) 
							   withObject:[NSNumber numberWithInt:5]
							waitUntilDone:YES];
	}
	if ([[defaults objectForKey:ACCOUNT1_NAME] isEqual:@""]&&[[defaults objectForKey:ACCOUNT2_NAME] isEqual:@""]) {
		[account1 performSelectorOnMainThread:@selector(setTitle:) 
								   withObject:emptyString 
								waitUntilDone:YES];
		[account2 performSelectorOnMainThread:@selector(setTitle:) 
								   withObject:emptyString 
								waitUntilDone:YES];
		[self performSelectorOnMainThread:@selector(setAccountStatus:) 
							   withObject:[NSNumber numberWithInt:1] 
							waitUntilDone:YES];
		[self performSelectorOnMainThread:@selector(setAccountStatus:) 
							   withObject:[NSNumber numberWithInt:3]
							waitUntilDone:YES];
		[self performSelectorOnMainThread:@selector(setAccountStatus:) 
							   withObject:[NSNumber numberWithInt:6] 
							waitUntilDone:YES];
		[self performSelectorOnMainThread:@selector(setConnectItemEnabled:) 
							   withObject:[NSNumber numberWithInt:0]
							waitUntilDone:YES];
	}else if ([[defaults objectForKey:ACCOUNT1_NAME] isEqual:@""]) {
		[account1 performSelectorOnMainThread:@selector(setTitle:) 
								   withObject:emptyString 
								waitUntilDone:YES];
		[account2 performSelectorOnMainThread:@selector(setTitle:) 
								   withObject:[defaults objectForKey:ACCOUNT2_NAME] 
								waitUntilDone:YES];
		[self performSelectorOnMainThread:@selector(setAccountStatus:) 
							   withObject:[NSNumber numberWithInt:1] 
							waitUntilDone:YES];
		[self performSelectorOnMainThread:@selector(setAccountStatus:) 
							   withObject:[NSNumber numberWithInt:5] 
							waitUntilDone:YES];
	}else if ([[defaults objectForKey:ACCOUNT2_NAME] isEqual:@""]) {
		[account2 performSelectorOnMainThread:@selector(setTitle:) 
								   withObject:emptyString 
								waitUntilDone:YES];
		[account1 performSelectorOnMainThread:@selector(setTitle:) 
								   withObject:[defaults objectForKey:ACCOUNT1_NAME] 
								waitUntilDone:YES];
		[self performSelectorOnMainThread:@selector(setAccountStatus:) 
							   withObject:[NSNumber numberWithInt:3] 
							waitUntilDone:YES];
		[self performSelectorOnMainThread:@selector(setAccountStatus:) 
							   withObject:[NSNumber numberWithInt:4] 
							waitUntilDone:YES];
	}else {
		[account1 performSelectorOnMainThread:@selector(setTitle:) 
								   withObject:[defaults objectForKey:ACCOUNT1_NAME] 
								waitUntilDone:YES];
		[account2 performSelectorOnMainThread:@selector(setTitle:) 
								   withObject:[defaults objectForKey:ACCOUNT2_NAME] 
								waitUntilDone:YES];
	}
	[consoleLock lock];
	[consoleContent setBackgroundColor:[NSColor colorWithCalibratedRed:0.0
																 green:0.0
																  blue:0.0
																 alpha:0.85]];
	[consoleContent setSelectedTextAttributes:[NSDictionary dictionaryWithObject:[NSColor disabledControlTextColor] forKey:NSBackgroundColorAttributeName]];
	[clearButton setEnabled:NO];
	[consoleLock unlock];
	selectedToolbarItem=-1;
	if ([defaults boolForKey:ENABLE_REMOTE_FUNCTION]) {
		autoStartButton=autoStartButton_alt;
		optionsView=optionsView_alt;
	}
	[self switchToAccount1];
	[self setStatus:0];
}
- (NSArray *) toolbarAllowedItemIdentifiers: (NSToolbar *) toolbar {
    return [NSArray arrayWithObjects:@"Account 1", @"Account 2",NSToolbarFlexibleSpaceItemIdentifier,@"Console",NSToolbarSeparatorItemIdentifier,@"Options", nil];
}

- (NSArray *) toolbarDefaultItemIdentifiers: (NSToolbar *)toolbar 
{
	return [NSArray arrayWithObjects:@"Account 1", @"Account 2", NSToolbarFlexibleSpaceItemIdentifier,@"Console",NSToolbarSeparatorItemIdentifier,@"Options",nil];
}

- (NSToolbarItem *)toolbar:(NSToolbar *)toolbar
     itemForItemIdentifier:(NSString *)itemIdentifier
 willBeInsertedIntoToolbar:(BOOL)flag
{
    NSToolbarItem *toolbarItem = nil;
	NSBundle *mainBundle = [NSBundle mainBundle];
	NSString *account1Tooltip = [mainBundle localizedStringForKey:ACCOUNT1_TOOLTIP
															value:@""
															table:nil];
	NSString *account2Tooltip = [mainBundle localizedStringForKey:ACCOUNT2_TOOLTIP
															value:@""
															table:nil];
	NSString *consoleTooltip = [mainBundle localizedStringForKey:CONSOLE_TOOLTIP
															value:@""
															table:nil];
	NSString *optionsTooltip = [mainBundle localizedStringForKey:OPTIONS_TOOLTIP
															value:@""
															table:nil];
	
    if ([itemIdentifier isEqual:@"Account 1"]) {
        toolbarItem = [[NSToolbarItem alloc] initWithItemIdentifier:itemIdentifier];
		
		NSBundle *mainBundle= [NSBundle mainBundle];
		NSString *string=[mainBundle localizedStringForKey:@"ACCOUNT 1" 
													 value:@"" 
													 table:nil];
		NSString *stringBuffer=[NSString stringWithFormat:string,0x00b9];
        [toolbarItem setLabel:stringBuffer];
        [toolbarItem setPaletteLabel:[toolbarItem label]];
        [toolbarItem setToolTip:account1Tooltip];
        [toolbarItem setImage:[NSImage imageNamed:@"Account 1.png"]];
        [toolbarItem setTarget:self];
        [toolbarItem setAction:@selector(switchToAccount1)];
    } else if([itemIdentifier isEqual:@"Account 2"]) {
		toolbarItem = [[NSToolbarItem alloc] initWithItemIdentifier:itemIdentifier];
		NSBundle *mainBundle= [NSBundle mainBundle];
		NSString *string=[mainBundle localizedStringForKey:@"ACCOUNT 1" 
													 value:@"" 
													 table:nil];
		NSString *stringBuffer=[NSString stringWithFormat:string,0x00b2];
        [toolbarItem setLabel:stringBuffer];
        [toolbarItem setPaletteLabel:[toolbarItem label]];
        [toolbarItem setToolTip:account2Tooltip];
        [toolbarItem setImage:[NSImage imageNamed:@"Account 2.png"]];
        [toolbarItem setTarget:self];
        [toolbarItem setAction:@selector(switchToAccount2)];
    } else if ([itemIdentifier isEqual:@"Options"]) {
		toolbarItem = [[NSToolbarItem alloc] initWithItemIdentifier:itemIdentifier];
		NSBundle *mainBundle= [NSBundle mainBundle];
		NSString *string=[mainBundle localizedStringForKey:OPTIONS_STRING 
													 value:@"" 
													 table:nil];
        [toolbarItem setLabel:string];
        [toolbarItem setPaletteLabel:[toolbarItem label]];
        [toolbarItem setToolTip:optionsTooltip];
        [toolbarItem setImage:[NSImage imageNamed:@"Options.png"]];
        [toolbarItem setTarget:self];
        [toolbarItem setAction:@selector(switchToOptions)];
	} else {
		toolbarItem = [[NSToolbarItem alloc] initWithItemIdentifier:itemIdentifier];
		NSBundle *mainBundle= [NSBundle mainBundle];
		NSString *string=[mainBundle localizedStringForKey:CONSOLE_STRING 
													 value:@"" 
													 table:nil];
        [toolbarItem setLabel:string];
        [toolbarItem setPaletteLabel:[toolbarItem label]];
        [toolbarItem setToolTip:consoleTooltip];
        [toolbarItem setImage:[NSImage imageNamed:@"Console.png"]];
        [toolbarItem setTarget:self];
        [toolbarItem setAction:@selector(switchToConsole)];
	}

    return [toolbarItem autorelease];
}
- (NSArray *)toolbarSelectableItemIdentifiers: (NSToolbar *)toolbar
{
    return [NSArray arrayWithObjects:@"Account 1", @"Account 2",@"Console", @"Options",nil];
}
-(void)switchToConsole{
	if (selectedToolbarItem==2) {
		return;
	}
	if ([saveButton isEnabled]) {
		NSBundle *mainBundle=[NSBundle mainBundle];
		NSString *chosenAccount;
		NSUserDefaults *defaults=[NSUserDefaults standardUserDefaults];
		if (selectedToolbarItem==0) {
			chosenAccount=[defaults objectForKey:ACCOUNT1_NAME];
		}else {
			chosenAccount=[defaults objectForKey:ACCOUNT2_NAME];
		}
		NSString *title=[mainBundle localizedStringForKey:SAVE_PROMOT_TITLE
													value:@""
													table:nil];
		NSString *button1=[mainBundle localizedStringForKey:SAVE_PROMOT_BUTTON1 
													 value:@""
													 table:nil];
		NSString *button2=[mainBundle localizedStringForKey:SAVE_PROMOT_BUTTON2
													 value:@""
													 table:nil];
		if ([chosenAccount isEqual:@""]) {
			NSString *content=[mainBundle localizedStringForKey:SAVE_PROMOT_CONTENT_ALERT
														  value:@""
														  table:nil];
			NSBeginAlertSheet(title, 
							  button1, 
							  button2,
							  nil,
							  mainWindow,
							  self,
							  @selector(sheetDidEnd:returnCode:contextInfo:),
							  nil,
							  @"console",
							  content);
		}else {
			NSString *content=[mainBundle localizedStringForKey:SAVE_PROMOT_CONTENT
														  value:@""
														  table:nil];
			NSBeginAlertSheet(title, 
							  button1, 
							  button2,
							  nil,
							  mainWindow,
							  self,
							  @selector(sheetDidEnd:returnCode:contextInfo:),
							  nil,
							  @"console",
							  [NSString stringWithFormat:content,chosenAccount]);
		}
		return;
	}
	NSBundle *mainBundle=[NSBundle mainBundle];
	NSString *windowTitle=[mainBundle localizedStringForKey:CONSOLE_STRING 
													  value:@""
													  table:nil];
	[mainWindow setTitle:windowTitle];
	NSView *tempView = [[NSView alloc] initWithFrame:[[mainWindow contentView] frame]];
	[mainWindow setContentView:tempView];
	selectedToolbarItem=2;
    [tempView release];
	NSRect newFrame = [mainWindow frame];
    newFrame.size.height = [terminalView frame].size.height + ([mainWindow frame].size.height - [[mainWindow contentView] frame].size.height);
    newFrame.size.width = [terminalView frame].size.width;
    newFrame.origin.y += ([[mainWindow contentView] frame].size.height - [terminalView frame].size.height);
	[mainWindow setShowsResizeIndicator:YES];
	if ([mainWindow isVisible]) {
		[mainWindow	setFrame:newFrame display:YES animate:YES];
	}else {
		[mainWindow	setFrame:newFrame display:YES animate:NO];
	}    
	[mainWindow setContentView:terminalView];
	[mainWindow setBackgroundColor:[NSColor colorWithCalibratedRed:0.0
															 green:0.0
															  blue:0.0
															 alpha:0.0]];
	[mainWindow setOpaque:NO];
}
-(void)switchToAccount1{
	if (selectedToolbarItem==0) {
		return;
	}
	if ([saveButton isEnabled]) {
		NSBundle *mainBundle=[NSBundle mainBundle];
		NSString *chosenAccount;
		NSUserDefaults *defaults=[NSUserDefaults standardUserDefaults];
		chosenAccount=[defaults objectForKey:ACCOUNT2_NAME];
		
		NSString *title=[mainBundle localizedStringForKey:SAVE_PROMOT_TITLE
													value:@""
													table:nil];
		NSString *button1=[mainBundle localizedStringForKey:SAVE_PROMOT_BUTTON1 
													  value:@""
													  table:nil];
		NSString *button2=[mainBundle localizedStringForKey:SAVE_PROMOT_BUTTON2
													  value:@""
													  table:nil];
		if ([chosenAccount isEqual:@""]) {
			NSString *content=[mainBundle localizedStringForKey:SAVE_PROMOT_CONTENT_ALERT
														  value:@""
														  table:nil];
			NSBeginAlertSheet(title, 
							  button1, 
							  button2,
							  nil,
							  mainWindow,
							  self,
							  @selector(sheetDidEnd:returnCode:contextInfo:),
							  nil,
							  @"account1",
							  content);
		}else {
			NSString *content=[mainBundle localizedStringForKey:SAVE_PROMOT_CONTENT
														  value:@""
														  table:nil];
			NSBeginAlertSheet(title, 
							  button1, 
							  button2,
							  nil,
							  mainWindow,
							  self,
							  @selector(sheetDidEnd:returnCode:contextInfo:),
							  nil,
							  @"account1",
							  [NSString stringWithFormat:content,chosenAccount]);
		}
		return;
	}
	NSUserDefaults *defaults=[NSUserDefaults standardUserDefaults];
	NSBundle *mainBundle=[NSBundle mainBundle];
	NSString *titleBuffer=[mainBundle localizedStringForKey:@"ACCOUNT 2" 
													  value:@""
													  table:nil];
	NSString *windowTitle=[NSString stringWithFormat:titleBuffer,0x00b9];
	int i;
	[mainWindow setBackgroundColor:[NSColor windowBackgroundColor]];
	[mainWindow setOpaque:YES];
	[mainWindow setTitle:windowTitle];
	[usernameField setStringValue:[defaults objectForKey:ACCOUNT1_NAME]];
	[passwordField setStringValue:@""];
	if ([[defaults objectForKey:ACCOUNT1_USEDOT1X] isEqual:@"1"]) {
		[useDot1x setState:NSOnState];
	}else {
		[useDot1x setState:NSOffState];
	}
	for(i=0;i<[interfaces numberOfItems];i++){
		if ([(NSString*)SCNetworkInterfaceGetBSDName((SCNetworkInterfaceRef)[networkInterfaces objectAtIndex:i]) isEqual:[defaults objectForKey:ACCOUNT1_ADAPTER]]) {
			[interfaces selectItemAtIndex:i];
			break;
		}
	}
	[type selectItemAtIndex:[[defaults objectForKey:ACCOUNT1_LIMITATION] intValue]];

	[saveButton setEnabled:NO];
	if ([[defaults objectForKey:ACCOUNT1_NAME] isEqual:@""]) {
		[deleteButton setEnabled:NO];
	}else {
		[deleteButton setEnabled:YES];
	}
	selectedToolbarItem=0;
	NSView *tempView = [[NSView alloc] initWithFrame:[[mainWindow contentView] frame]];
	[mainWindow setContentView:tempView];
    [tempView release];
	NSRect newFrame = [mainWindow frame];
    newFrame.size.height = [accountView frame].size.height + ([mainWindow frame].size.height - [[mainWindow contentView] frame].size.height);
    newFrame.size.width = [accountView frame].size.width;
    newFrame.origin.y += ([[mainWindow contentView] frame].size.height - [accountView frame].size.height);
	[mainWindow setShowsResizeIndicator:YES];
	if ([mainWindow isVisible]) {
		[mainWindow	setFrame:newFrame display:YES animate:YES];
	}else {
		[mainWindow	setFrame:newFrame display:YES animate:NO];
	}

    
	[mainWindow setContentView:accountView];
}
-(void)switchToAccount2{
	if (selectedToolbarItem==1) {
		return;
	}
	if ([saveButton isEnabled]) {
		NSBundle *mainBundle=[NSBundle mainBundle];
		NSString *chosenAccount;
		NSUserDefaults *defaults=[NSUserDefaults standardUserDefaults];
		chosenAccount=[defaults objectForKey:ACCOUNT1_NAME];
		
		NSString *title=[mainBundle localizedStringForKey:SAVE_PROMOT_TITLE
													value:@""
													table:nil];
		NSString *button1=[mainBundle localizedStringForKey:SAVE_PROMOT_BUTTON1 
													  value:@""
													  table:nil];
		NSString *button2=[mainBundle localizedStringForKey:SAVE_PROMOT_BUTTON2
													  value:@""
													  table:nil];
		if ([chosenAccount isEqual:@""]) {
			NSString *content=[mainBundle localizedStringForKey:SAVE_PROMOT_CONTENT_ALERT
														  value:@""
														  table:nil];
			NSBeginAlertSheet(title, 
							  button1, 
							  button2,
							  nil,
							  mainWindow,
							  self,
							  @selector(sheetDidEnd:returnCode:contextInfo:),
							  nil,
							  @"account2",
							  content);
		}else {
			NSString *content=[mainBundle localizedStringForKey:SAVE_PROMOT_CONTENT
														  value:@""
														  table:nil];
			NSBeginAlertSheet(title, 
							  button1, 
							  button2,
							  nil,
							  mainWindow,
							  self,
							  @selector(sheetDidEnd:returnCode:contextInfo:),
							  nil,
							  @"account2",
							  [NSString stringWithFormat:content,chosenAccount]);
		}
		return;
	}
	NSUserDefaults *defaults=[NSUserDefaults standardUserDefaults];
	int i;
	NSBundle *mainBundle=[NSBundle mainBundle];
	NSString *titleBuffer=[mainBundle localizedStringForKey:@"ACCOUNT 2" 
													  value:@""
													  table:nil];
	NSString *windowTitle=[NSString stringWithFormat:titleBuffer,0x00b2];
	[mainWindow setBackgroundColor:[NSColor windowBackgroundColor]];
	[mainWindow setOpaque:YES];
	[mainWindow setTitle:windowTitle];
	
	[usernameField setStringValue:[defaults objectForKey:ACCOUNT2_NAME]];
	[passwordField setStringValue:@""];
	if ([[defaults objectForKey:ACCOUNT2_USEDOT1X] isEqual:@"1"]) {
		[useDot1x setState:NSOnState];
	}else {
		[useDot1x setState:NSOffState];
	}
	for(i=0;i<[interfaces numberOfItems];i++){
		
		if ([(NSString*)SCNetworkInterfaceGetBSDName((SCNetworkInterfaceRef)[networkInterfaces objectAtIndex:i]) isEqual:[defaults objectForKey:ACCOUNT2_ADAPTER]]) {
			[interfaces selectItemAtIndex:i];
			break;
		}
	}
	[type selectItemAtIndex:[[defaults objectForKey:ACCOUNT2_LIMITATION] intValue]];
	 
	[saveButton setEnabled:NO];
	if ([[defaults objectForKey:ACCOUNT2_NAME] isEqual:@""]) {
		[deleteButton setEnabled:NO];
	}else {
		[deleteButton setEnabled:YES];
	}

	selectedToolbarItem=1;
	NSView *tempView = [[NSView alloc] initWithFrame:[[mainWindow contentView] frame]];
	[mainWindow setContentView:tempView];
    [tempView release];
	NSRect newFrame = [mainWindow frame];
    newFrame.size.height = [accountView frame].size.height + ([mainWindow frame].size.height - [[mainWindow contentView] frame].size.height);
    newFrame.size.width = [accountView frame].size.width;
    newFrame.origin.y += ([[mainWindow contentView] frame].size.height - [accountView frame].size.height);
	[mainWindow setShowsResizeIndicator:YES];
    if ([mainWindow isVisible]) {
		[mainWindow	setFrame:newFrame display:YES animate:YES];
	}else {
		[mainWindow	setFrame:newFrame display:YES animate:NO];
	}

	[mainWindow setContentView:accountView];
}
-(void)switchToOptions{
	NSUserDefaults *defaults=[NSUserDefaults standardUserDefaults];
	if (selectedToolbarItem==3) {
		return;
	}
	if ([saveButton isEnabled]) {
		NSBundle *mainBundle=[NSBundle mainBundle];
		NSString *chosenAccount;
		if (selectedToolbarItem==0) {
			chosenAccount=[defaults objectForKey:ACCOUNT1_NAME];
		}else {
			chosenAccount=[defaults objectForKey:ACCOUNT2_NAME];
		}
		NSString *title=[mainBundle localizedStringForKey:SAVE_PROMOT_TITLE
													value:@""
													table:nil];
		NSString *button1=[mainBundle localizedStringForKey:SAVE_PROMOT_BUTTON1 
													  value:@""
													  table:nil];
		NSString *button2=[mainBundle localizedStringForKey:SAVE_PROMOT_BUTTON2
													  value:@""
													  table:nil];
		if ([chosenAccount isEqual:@""]) {
			NSString *content=[mainBundle localizedStringForKey:SAVE_PROMOT_CONTENT_ALERT
														  value:@""
														  table:nil];
			NSBeginAlertSheet(title, 
							  button1, 
							  button2,
							  nil,
							  mainWindow,
							  self,
							  @selector(sheetDidEnd:returnCode:contextInfo:),
							  nil,
							  @"options",
							  content);
		}else {
			NSString *content=[mainBundle localizedStringForKey:SAVE_PROMOT_CONTENT
														  value:@""
														  table:nil];
			NSBeginAlertSheet(title, 
							  button1, 
							  button2,
							  nil,
							  mainWindow,
							  self,
							  @selector(sheetDidEnd:returnCode:contextInfo:),
							  nil,
							  @"options",
							  [NSString stringWithFormat:content,chosenAccount]);
		}
		return;
	}
	if ([UKLoginItemRegistry isAppSetToRunAtLogon]) {
		[autoStartButton setState:NSOnState];
	}else {
		[autoStartButton setState:NSOffState];
	}
	if ([defaults boolForKey:ENABLE_REMOTE_FUNCTION]) {

		if ([defaults boolForKey:ALLOW_REMOTE]) {
			[alowRemote setState:NSOnState];
			[startServiceButton setEnabled:YES];
		}else {
			[alowRemote setState:NSOffState];
			[startServiceButton setEnabled:NO];
		}

	}
	NSBundle *mainBundle=[NSBundle mainBundle];
	NSString *windowTitle=[mainBundle localizedStringForKey:OPTIONS_STRING 
													  value:@""
													  table:nil];
	[mainWindow setBackgroundColor:[NSColor windowBackgroundColor]];
	[mainWindow setOpaque:YES];
	[mainWindow setTitle:windowTitle];
	NSView *tempView = [[NSView alloc] initWithFrame:[[mainWindow contentView] frame]];
	[mainWindow setContentView:tempView];
	selectedToolbarItem=3;
    [tempView release];
	NSRect newFrame = [mainWindow frame];
    newFrame.size.height = [optionsView frame].size.height + ([mainWindow frame].size.height - [[mainWindow contentView] frame].size.height);
    newFrame.size.width = [optionsView frame].size.width;
    newFrame.origin.y += ([[mainWindow contentView] frame].size.height - [optionsView frame].size.height);
	[mainWindow setShowsResizeIndicator:YES];
	if ([mainWindow isVisible]) {
		[mainWindow	setFrame:newFrame display:YES animate:YES];
	}else {
		[mainWindow	setFrame:newFrame display:YES animate:NO];
	}
	[mainWindow setContentView:optionsView];
}
-(IBAction)connect:(id)sender{
	if (connectJustPressed) {
		return;
	}
	connectJustPressed=YES;
	if (![mainConnect isExecuting]) {
		if ([account1 state]==NSOffState&&[account2 state]==NSOffState) {
			NSLog(@"No account avaliable.\n");
			return;
		}
		[self setStatus:1];
		NSUserDefaults *defaults=[NSUserDefaults standardUserDefaults];
		CHAR password[200];
		BYTE tmp[16];
		int i, count,uid;
		ETHCARD_INFO ethcards[16];
		if ([account1 state]==NSOnState) {
			
			strcpy(g_UserConfig.szUsername, (char *)[[defaults objectForKey:ACCOUNT1_NAME] UTF8String]);
			MD5Buffer(g_UserConfig.szUsername, strlen(g_UserConfig.szUsername), g_UserConfig.md5Username);
			buf2hex(g_UserConfig.md5Username, 16, g_UserConfig.szMD5Username);
			DecodePasswordByUsername((char *)[[defaults objectForKey:ACCOUNT1_NAME] UTF8String], 
									 (char *)[[defaults objectForKey:ACCOUNT1_PASSWORD] UTF8String], password);
			
			strcpy(g_UserConfig.szMD5Password, "");
			if(password)
				strcpy(g_UserConfig.szMD5Password, password);
			memcpy(g_UserConfig.md5Password, hex2buf(password, tmp, NULL), 16);
			count = get_ethcards(ethcards, sizeof(ethcards));
			strcpy(g_UserConfig.szAdaptor, (char *)[[defaults objectForKey:ACCOUNT1_ADAPTER] UTF8String]);
			for(i = 0;i < count;i ++)
			{
				if(strcmp(ethcards[i].name, (char *)[[defaults objectForKey:ACCOUNT1_ADAPTER] UTF8String]) == 0)
				{
					strcpy(g_UserConfig.szMac, ethcards[i].mac);
					strcpy(g_UserConfig.szIp, ethcards[i].ip);
					break;
				}
			}
			if ([[defaults objectForKey:ACCOUNT1_LIMITATION] isEqual:@"0"]) {
				g_UserConfig.limitation=LIMITATION_CAMPUS;
			}else if ([[defaults objectForKey:ACCOUNT1_LIMITATION] isEqual:@"1"]) {
				g_UserConfig.limitation=LIMITATION_DOMESTIC;
			}else {
				g_UserConfig.limitation=LIMITATION_NONE;
			}
			NSUserDefaults *defaults=[NSUserDefaults standardUserDefaults];
			NSArray *languages=[defaults objectForKey:@"AppleLanguages"];
			NSString *language=[languages objectAtIndex:0];
			if ([language isEqual:@"zh-Hans"]) {
				g_UserConfig.language=1;
			}else {
				g_UserConfig.language=0;
			}
			
			g_UserConfig.bUseDot1x=[[defaults objectForKey:ACCOUNT1_USEDOT1X] intValue];
			g_UserConfig.bRetryDot1x=0;
			
		}else{
			strcpy(g_UserConfig.szUsername, (char *)[[defaults objectForKey:ACCOUNT2_NAME] UTF8String]);
			MD5Buffer(g_UserConfig.szUsername, strlen(g_UserConfig.szUsername), g_UserConfig.md5Username);
			buf2hex(g_UserConfig.md5Username, 16, g_UserConfig.szMD5Username);
			DecodePasswordByUsername((char *)[[defaults objectForKey:ACCOUNT2_NAME] UTF8String], 
									 (char *)[[defaults objectForKey:ACCOUNT2_PASSWORD] UTF8String], password);
			
			strcpy(g_UserConfig.szMD5Password, "");
			if(password)
				strcpy(g_UserConfig.szMD5Password, password);
			memcpy(g_UserConfig.md5Password, hex2buf(password, tmp, NULL), 16);
			count = get_ethcards(ethcards, sizeof(ethcards));
			strcpy(g_UserConfig.szAdaptor, (char *)[[defaults objectForKey:ACCOUNT2_ADAPTER] UTF8String]);
			for(i = 0;i < count;i ++)
			{
				if(strcmp(ethcards[i].name, (char *)[[defaults objectForKey:ACCOUNT2_ADAPTER] UTF8String]) == 0)
				{
					strcpy(g_UserConfig.szMac, ethcards[i].mac);
					strcpy(g_UserConfig.szIp, ethcards[i].ip);
					break;
				}
			}
			if ([[defaults objectForKey:ACCOUNT2_LIMITATION] isEqual:@"0"]) {
				g_UserConfig.limitation=LIMITATION_CAMPUS;
			}else if ([[defaults objectForKey:ACCOUNT2_LIMITATION] isEqual:@"1"]) {
				g_UserConfig.limitation=LIMITATION_DOMESTIC;
			}else {
				g_UserConfig.limitation=LIMITATION_NONE;
			}
			NSUserDefaults *defaults=[NSUserDefaults standardUserDefaults];
			NSArray *languages=[defaults objectForKey:@"AppleLanguages"];
			NSString *language=[languages objectAtIndex:0];
			if ([language isEqual:@"zh-Hans"]) {
				g_UserConfig.language=1;
			}else {
				g_UserConfig.language=0;
			}
			g_UserConfig.bUseDot1x=[[defaults objectForKey:ACCOUNT2_USEDOT1X] intValue];
			g_UserConfig.bRetryDot1x=0;
		}

		if (g_UserConfig.bUseDot1x) {
			uid=geteuid();
			printf("EUID=%d\n",uid);
			if (uid!=0) {
				[self setStatus:0];
				connectJustPressed=NO;
				NSBundle *mainBundle=[NSBundle mainBundle];
				alertContent = [mainBundle localizedStringForKey:ALERT_STRING 
														   value:@"" 
														   table:nil];
				alertTitle = [mainBundle localizedStringForKey:ALERT_TITLE_STRING 
														 value:@"" 
														 table:nil];
				alertButton = [mainBundle localizedStringForKey:QUIT_STRING 
														  value:@"" 
														  table:nil];
				NSBeep();
				NSRunAlertPanel(alertTitle,
								alertContent,
								alertButton, nil, nil);
				return;
			}
		}
		[mainConnect release];
		[flagLock lock];
		mytunetsvc_stop_flag=0;
		[flagLock unlock];
		mainConnect = [[NSThread alloc] initWithTarget:self 
											  selector:@selector(tryConnection) 
												object:nil];
		
		[mainConnect start];
		connectJustPressed=NO;
	}else {
		if (statusTitle==3) {
			return;
		}
		[self setStatus:3];
		[flagLock lock];
		mytunetsvc_stop_flag=1;
		[flagLock unlock];
		[condition lock];
		[condition signal];
		[condition unlock];
		connectJustPressed=NO;
	}

	
}
#define WAITING_FOR_CLIENT 0
#define SECURE_FAILED 1
#define SECURE_PASSED 2
#define RECV_CONNECT 3
#define RECV_DISCONNECT 4
#define RETURN_ACCOUNT 5
#define REMOTE_DEBUG 0

-(void)remote{
	NSAutoreleasePool *pool=[[NSAutoreleasePool alloc] init];
	int remote_socket_listen=0,remote_socket_accept=0;
	int cli_len,ret,flags;
	struct sockaddr_in addr_server,addr_client;
	char data_buf[256];
	char pass_buffer[33];
	int recv_len;
	struct timeval tv;
	tv.tv_sec=3;
	tv.tv_usec=0;
	fd_set rset;
	fd_set eset;
	BOOL securePassed=NO;
	int remote_server_status;
	int fail_count=0;
	NSUserDefaults *defaults=[NSUserDefaults standardUserDefaults];
	NSBundle *mainBundle=[NSBundle mainBundle];
	NSString *returnAccountString;
	NSString *stopServiceTitle=[mainBundle localizedStringForKey:STOP_SERVICE
														   value:@""
															table:nil];
	NSString *serviceRunning = [mainBundle localizedStringForKey:SERVICE_RUNNING
														   value:@""
															table:nil];
	
	[startServiceButton performSelectorOnMainThread:@selector(setTitle:)
										 withObject:stopServiceTitle
									  waitUntilDone:YES];
	NSMutableAttributedString *serviceString=[[NSMutableAttributedString alloc] initWithString:serviceRunning];
	[serviceString addAttribute:NSForegroundColorAttributeName
						  value:[NSColor greenColor]
						  range:NSMakeRange(0, [serviceString length])];
	[serviceIndicator performSelectorOnMainThread:@selector(setAttributedStringValue:)
									   withObject:serviceString
									waitUntilDone:YES];
	[serviceString release];
	remote_socket_listen=socket(AF_INET, SOCK_STREAM, 0);
	if (remote_socket_listen<0) {
		[self closeRemoteListenSocket:remote_socket_listen
						 acceptSocket:remote_socket_accept
							 withPool:pool];
		return;
	}
	if (REMOTE_DEBUG) {
		printf("remote_socket_listen created.\n");
	}
	addr_server.sin_family=AF_INET;
	addr_server.sin_port=htons(portNumber);
	addr_server.sin_addr.s_addr=htonl(INADDR_ANY);
	if (bind(remote_socket_listen,(struct sockaddr*)&addr_server, (socklen_t)sizeof(addr_server))<0) {
		[self closeRemoteListenSocket:remote_socket_listen
						 acceptSocket:remote_socket_accept
							 withPool:pool];
		return;
	}
	if (REMOTE_DEBUG) {
		printf("remote_socket_listen non-block set.\n");
	}
	if (listen(remote_socket_listen, 3)<0) {
		[self closeRemoteListenSocket:remote_socket_listen
						 acceptSocket:remote_socket_accept
							 withPool:pool];
		return;
	}
	cli_len=sizeof(addr_client);
	
	while (!stopService) {
		remote_socket_accept=accept(remote_socket_listen, (struct sockaddr *)&addr_client, (socklen_t *)&cli_len);
		if (remote_socket_accept<0) {
			[self closeRemoteListenSocket:remote_socket_listen
							 acceptSocket:remote_socket_accept
								 withPool:pool];
			return;
		}
		if ((flags=fcntl(remote_socket_accept, F_GETFL,0))<0) {
			[self closeRemoteListenSocket:remote_socket_listen
							 acceptSocket:remote_socket_accept
								 withPool:pool];
			return;
		}
		if (fcntl(remote_socket_accept,F_SETFL,flags|O_NONBLOCK)<0) {
			[self closeRemoteListenSocket:remote_socket_listen
							 acceptSocket:remote_socket_accept
								 withPool:pool];
			return;
		}
		if (REMOTE_DEBUG) {
			printf("Trying accept.\n");
		}
		securePassed=NO;
		remote_server_status=WAITING_FOR_CLIENT;
		FD_ZERO(&rset);
		FD_ZERO(&eset);
		FD_SET(remote_socket_accept, &rset);
		FD_SET(remote_socket_accept, &eset);
		fail_count=0;
		if (REMOTE_DEBUG) {
			printf("In loop 2.\n");
		}
		if (fail_count>=5) {
			if (REMOTE_DEBUG) {
				printf("Retried 5 times.\n");
			}
			[self closeRemoteListenSocket:remote_socket_listen
							 acceptSocket:remote_socket_accept
								 withPool:pool];
			return;
		}
		ret=select(remote_socket_accept+1,&rset,NULL,&eset,&tv);
		if (ret<0) {
			[self closeRemoteListenSocket:remote_socket_listen
							 acceptSocket:remote_socket_accept
								 withPool:pool];
			return;
		}
		else if (ret==0) {
			if (REMOTE_DEBUG) {
				printf("loop 2 select timeout.\n");
			}
		}
		else {
			if (FD_ISSET(remote_socket_accept, &eset)) {
				if (REMOTE_DEBUG) {
					printf("loop 2 error.\n");
				}
				[self closeRemoteListenSocket:remote_socket_listen
								 acceptSocket:remote_socket_accept
									 withPool:pool];
				return;
			}
			if (FD_ISSET(remote_socket_accept, &rset)) {
				if (REMOTE_DEBUG) {
					printf("loop 2 read ready.\n");
				}
				recv_len=recv(remote_socket_accept, data_buf, 256,0);
				switch (data_buf[0]) {
					case 0:
						if (recv_len>=33) {
							memcpy(pass_buffer, data_buf+1, 32*sizeof(char));
							pass_buffer[32]='\0';
							if (REMOTE_DEBUG) {
								printf("password request. %s\n",pass_buffer);
							}
							if ([defaults objectForKey:REMOTE_PASSWORD]==nil) {
								[self closeRemoteListenSocket:remote_socket_listen
												 acceptSocket:remote_socket_accept
													 withPool:pool];
								return;
							}
							if (!strcmp(pass_buffer, [[defaults objectForKey:REMOTE_PASSWORD] UTF8String])) {
								securePassed=YES;
								remote_server_status=SECURE_PASSED;
							}else {
								remote_server_status=SECURE_FAILED;
							}
							
						}else {
							remote_server_status=SECURE_FAILED;
						}

						break;
					case 1:
						if (recv_len>=33) {
							memcpy(pass_buffer, data_buf+1, 32*sizeof(char));
							pass_buffer[32]='\0';
							if (REMOTE_DEBUG) {
								printf("password request. %s\n",pass_buffer);
							}
							if ([defaults objectForKey:REMOTE_PASSWORD]==nil) {
								[self closeRemoteListenSocket:remote_socket_listen
												 acceptSocket:remote_socket_accept
													 withPool:pool];
								return;
							}
							if (!strcmp(pass_buffer, [[defaults objectForKey:REMOTE_PASSWORD] UTF8String])) {
								securePassed=YES;
								remote_server_status=SECURE_PASSED;
							}else {
								remote_server_status=SECURE_FAILED;
							}
							
						}else {
							remote_server_status=SECURE_FAILED;
						}
						break;
					case 2:
						if (recv_len>=33) {
							memcpy(pass_buffer, data_buf+1, 32*sizeof(char));
							pass_buffer[32]='\0';
							if (REMOTE_DEBUG) {
								printf("password request. %s\n",pass_buffer);
							}
							if ([defaults objectForKey:REMOTE_PASSWORD]==nil) {
								[self closeRemoteListenSocket:remote_socket_listen
												 acceptSocket:remote_socket_accept
													 withPool:pool];
								return;
							}
							if (!strcmp(pass_buffer, [[defaults objectForKey:REMOTE_PASSWORD] UTF8String])) {
								securePassed=YES;
								if (statusTitle==0) {
									NSNotificationCenter *nc=[NSNotificationCenter defaultCenter];
									[nc postNotificationName:@"connectCallByRemote" object:self];
									
									remote_server_status=RECV_CONNECT;
								}else {
									remote_server_status=SECURE_PASSED;
								}
							}else {
								remote_server_status=SECURE_FAILED;
							}
							
						}else {
							remote_server_status=SECURE_FAILED;
						}
						
						break;
					case 3:
						if (recv_len>=33) {
							memcpy(pass_buffer, data_buf+1, 32*sizeof(char));
							pass_buffer[32]='\0';
							if (REMOTE_DEBUG) {
								printf("password request. %s\n",pass_buffer);
							}
							if ([defaults objectForKey:REMOTE_PASSWORD]==nil) {
								[self closeRemoteListenSocket:remote_socket_listen
												 acceptSocket:remote_socket_accept
													 withPool:pool];
								return;
							}
							if (!strcmp(pass_buffer, [[defaults objectForKey:REMOTE_PASSWORD] UTF8String])) {
								securePassed=YES;
								if (statusTitle==1||statusTitle==2) {
									NSNotificationCenter *nc=[NSNotificationCenter defaultCenter];
									[nc postNotificationName:@"connectCallByRemote" object:self];
									remote_server_status=RECV_DISCONNECT;
								}else {
									remote_server_status=SECURE_PASSED;
								}
							}else {
								remote_server_status=SECURE_FAILED;
							}
							
						}else {
							remote_server_status=SECURE_FAILED;
						}
						break;
					case 4:
						if (recv_len>=33) {
							memcpy(pass_buffer, data_buf+1, 32*sizeof(char));
							pass_buffer[32]='\0';
							if (REMOTE_DEBUG) {
								printf("password request. %s\n",pass_buffer);
							}
							if ([defaults objectForKey:REMOTE_PASSWORD]==nil) {
								[self closeRemoteListenSocket:remote_socket_listen
												 acceptSocket:remote_socket_accept
													 withPool:pool];
								return;
							}
							if (!strcmp(pass_buffer, [[defaults objectForKey:REMOTE_PASSWORD] UTF8String])) {
								securePassed=YES;
							}else {
								remote_server_status=SECURE_FAILED;
							}
							
						}else {
							remote_server_status=SECURE_FAILED;
						}
						break;
					case 5:
						if (recv_len>=33) {
							memcpy(pass_buffer, data_buf+1, 32*sizeof(char));
							pass_buffer[32]='\0';
							if (REMOTE_DEBUG) {
								printf("password request. %s\n",pass_buffer);
							}
							if ([defaults objectForKey:REMOTE_PASSWORD]==nil) {
								[self closeRemoteListenSocket:remote_socket_listen
												 acceptSocket:remote_socket_accept
													 withPool:pool];
								return;
							}
							if (!strcmp(pass_buffer, [[defaults objectForKey:REMOTE_PASSWORD] UTF8String])) {
								securePassed=YES;
								if ([account1 state]==NSOffState && [account2 state]==NSOffState) {
									returnAccountString = [[NSString alloc] initWithString:@"No account"];
								}else if ([account1 state] ==NSOnState) {
									if (![[[NSUserDefaults standardUserDefaults] objectForKey:ACCOUNT2_NAME] isEqual:@""]) {
										[self performSelectorOnMainThread:@selector(chooseAccount:)
															   withObject:account2
															waitUntilDone:YES];
										returnAccountString = [[NSString alloc] initWithString:[account2 title]];
									}else {
										returnAccountString = [[NSString alloc] initWithString:[account1 title]];
									}

								}else {
									if (![[[NSUserDefaults standardUserDefaults] objectForKey:ACCOUNT1_NAME] isEqual:@""]) {
										[self performSelectorOnMainThread:@selector(chooseAccount:)
															   withObject:account1
															waitUntilDone:YES];
										returnAccountString = [[NSString alloc] initWithString:[account1 title]];
									}else {
										returnAccountString = [[NSString alloc] initWithString:[account2 title]];
									}
								}
								remote_server_status=RETURN_ACCOUNT;
							}else {
								remote_server_status=SECURE_FAILED;
							}
							
						}else {
							remote_server_status=SECURE_FAILED;
						}
						break;
					default:
						remote_server_status=SECURE_FAILED;
						break;
				}
				if (remote_server_status==SECURE_FAILED) {
					memset(pass_buffer, '\0', sizeof(char)*33);
					pass_buffer[0]=0x00;
					send(remote_socket_accept, pass_buffer, 33, 0);
				}else if (remote_server_status==SECURE_PASSED||remote_server_status==RECV_CONNECT||remote_server_status==RECV_DISCONNECT) {
					memset(pass_buffer, '\0', sizeof(char)*33);
					pass_buffer[0]=0x01;
					switch (statusTitle) {
						case 0:
							pass_buffer[1]=0x00;
							break;
						case 1:
							pass_buffer[1]=0x01;
							break;
						case 2:
							pass_buffer[1]=0x02;
							break;
						default:
							pass_buffer[1]=0x03;
							break;
					}
					send(remote_socket_accept, pass_buffer, 33, 0);
				}else if (remote_server_status==RETURN_ACCOUNT) {
					memset(pass_buffer, '\0', sizeof(char)*33);
					pass_buffer[0]=0x02;
					strcpy(pass_buffer+1, [returnAccountString UTF8String]);
					send(remote_socket_accept, pass_buffer, 33, 0);
					[returnAccountString release];
				}
			}
			
		}
		close(remote_socket_accept);
		
	}
	[self closeRemoteListenSocket:remote_socket_listen
					 acceptSocket:remote_socket_accept
						 withPool:pool];
	
}
-(void)closeRemoteListenSocket:(int)listen_socket 
				  acceptSocket:(int)accept_socket
					  withPool:(NSAutoreleasePool *)pool{
	if (listen_socket>0) {
		close(listen_socket);
	}
	if (accept_socket>0) {
		close(accept_socket);
	}
	NSNotificationCenter *nc=[NSNotificationCenter defaultCenter];
	[nc postNotificationName:@"remoteControlDidEnd" object:self];
	[pool release];
}
-(void)tryConnection{
	
	NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
	BYTE tmpbuf[1024];
	
    BOOL_T bDot1xSuccess = FALSE;
    BOOL_T bDot1xFailure = FALSE;
    BOOL_T bNetworkError = FALSE;
    BOOL_T bTunetFailure = FALSE;
    BOOL_T bTunetSuccess = FALSE;
    BOOL_T bKeepAliveError = FALSE;
	
    LOG *log = NULL;
	
    TICK *retry_timer = os_tick_new(10000, TRUE);
    TICK *state_timer = os_tick_new(1000, TRUE);
    INT nDot1xRetryCount = 0, nTunetRetryCount = 0;
    INT nRetryDelay = 5000;
	
    mytunetsvc_login();
	fflush(stdout);
	BOOL deep_sleep;
	
    while(!mytunetsvc_stop_flag)
    {
		deep_sleep=YES;
        if(g_Goal == GOAL_RELOGIN)
        {
			
            tunet_stop();
			
            g_DelayRetry = DELAY_RETRY_NONE;
            nDot1xRetryCount = 0;
            nTunetRetryCount = 0;
			
            tunet_reset();
            dot1x_reset();
			
            g_Goal = GOAL_LOGIN;
        }
		
		
        if(os_tick_check(state_timer))
        {
            g_logs = logs_append(g_logs, "MYTUNETSVC_LIMITATION", NULL, (BYTE *)&g_UserConfig.limitation,  sizeof(g_UserConfig.limitation));
			
            tmpbuf[0] = dot1x_get_state();
            tmpbuf[1] = tunet_get_state();
            g_logs = logs_append(g_logs, "MYTUNETSVC_STATE", NULL, tmpbuf, 2);
			
        }
		
		
        if(g_DelayRetry != DELAY_RETRY_NONE)
        {
			
            if(os_tick_check(retry_timer))
            {
                switch(g_DelayRetry)
                {
                    case DELAY_RETRY_DOT1X:
                        if( dot1x_get_state() == DOT1X_STATE_NONE
						   || dot1x_get_state() == DOT1X_STATE_FAILURE)
                        {
                            nDot1xRetryCount ++;
                            dot1x_start(&g_UserConfig);
                        }
                        break;
                    case DELAY_RETRY_TUNET:
                        if( tunet_get_state() == TUNET_STATE_NONE
						   || tunet_get_state() == TUNET_STATE_FAILURE
						   || tunet_get_state() == TUNET_STATE_ERROR )
                        {
                            nTunetRetryCount ++;
                            tunet_start(&g_UserConfig);
                        }
                        break;
                }
                g_DelayRetry = DELAY_RETRY_NONE;
            }
            else
            {
				os_sleep(100);
            }
        }
		
		
		
        if(g_Goal == GOAL_LOGIN)
        {
            if(g_UserConfig.bUseDot1x)
            {
                if( dot1x_get_state() == DOT1X_STATE_NONE )
                {
                    dot1x_start(&g_UserConfig);
                }
				
                if( dot1x_get_state() == DOT1X_STATE_SUCCESS )
                {
                    if( tunet_get_state() == TUNET_STATE_NONE )
                    {
                        tunet_start(&g_UserConfig);
                    }
                }
                else
                {
                    if(dot1x_is_timeout())
                    {
                        dot1x_start(&g_UserConfig);
                    }
                }
            }
            else
            {
                if( tunet_get_state() == TUNET_STATE_NONE )
                {
                    tunet_start(&g_UserConfig);
                }
            }
			
			
            if(tunet_is_keepalive_timeout())
            {
                tunet_reset();
                if(g_UserConfig.bUseDot1x)
                    dot1x_start(&g_UserConfig);
                else
                    tunet_start(&g_UserConfig);
            }
        }
        else if(g_Goal == GOAL_LOGOUT)
        {
            tunet_stop();
            g_Goal = GOAL_NONE;
        }
		fflush(stdout);
		
		
RefetchLog:
        log = logs_fetch(g_logs, 0);
		
        if(log)
        {
			deep_sleep=NO;
			
			
#define TagIs(s) (strcmp(log->tag, s) == 0)
#define StrIs(s) (strcmp(log->str, s) == 0)
			
            bDot1xSuccess = FALSE;
            bDot1xFailure = FALSE;
            bNetworkError = FALSE;
            bTunetFailure = FALSE;
            bTunetSuccess = FALSE;
            bKeepAliveError = FALSE;
			
			if (strcmp(log->tag, "MYTUNETSVC_STATE")&&strcmp(log->tag, "MYTUNETSVC_LIMITATION")) {
				NSDateFormatter *dateFormatter=[[NSDateFormatter alloc] init];
				[dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
				[dateFormatter setFormatterBehavior:NSDateFormatterBehavior10_4];
				NSString *timeString=[[dateFormatter stringFromDate:[NSDate date]] retain];
				NSString *logString;
				if (log->str!=NULL) {
					if (g_UserConfig.language) {
						NSStringEncoding enc = CFStringConvertEncodingToNSStringEncoding (kCFStringEncodingGB_18030_2000);
						logString=[[NSString stringWithCString:log->str encoding:enc] retain];
					}else {
						logString=[[NSString stringWithUTF8String:log->str] retain];
					}

				}else {
					logString=[[NSString stringWithString:@""] retain];
				}
				
				NSString *string = [[NSString alloc] initWithFormat:@"%@: %s %@\n",timeString,log->tag, logString];
				[timeString release];
				[logString release];
				[self performSelectorOnMainThread:@selector(setConsoleString:)
									   withObject:string
									waitUntilDone:YES];
				[string release];
				[dateFormatter release];
			}
			
								
            if (TagIs("DOT1X_RECV_PACK" ))
            {
                if (StrIs("EAP_SUCCESS" ))  bDot1xSuccess = TRUE;
                if (StrIs("EAP_FAILURE" ))  bDot1xFailure = TRUE;
            }
			
            if (TagIs("TUNET_NETWORK_ERROR" ))  {
				bNetworkError = TRUE;
				[self setStatus:1];
			}
            if (TagIs("TUNET_LOGON_ERROR" )) {
				bTunetFailure = TRUE;
				NSBeep();
				NSBundle *mainBundle=[NSBundle mainBundle];
				NSString *logonErrorTitle=[mainBundle localizedStringForKey:LOGON_ERROR
																	  value:@""
																	  table:nil];
				NSStringEncoding enc = CFStringConvertEncodingToNSStringEncoding (kCFStringEncodingGB_18030_2000);
				NSString *logonErrorContent=[NSString stringWithCString:log->str
															   encoding:enc];
				NSString *logonErrorButton0=[mainBundle localizedStringForKey:OK_BUTTON
																	   value:@""
																	   table:nil];
				NSString *logonErrorButton1=[mainBundle localizedStringForKey:LOGON_ERROR_BUTTON
																	   value:@""
																	   table:nil];
				int ret=NSRunAlertPanel(logonErrorTitle,
								logonErrorContent,
								logonErrorButton0,
								logonErrorButton1,
								nil);
				if (ret!=1) {
					[self setStatus:3];
					break;
				}
			}
            if (TagIs("TUNET_LOGON_KEEPALIVE_SERVER" ))  {
				bTunetSuccess = TRUE;
				NSLog(@"Successfully login.\n");
				[self setStatus:2];
				if (![money isEqual:@""]) {
					[self setStatus:4];
				}
			}
			if (TagIs("TUNET_KEEPALIVE_MONEY" ))  {
				NSLog(@"Money: %s\n",log->str);
				[money release];
				money = [[NSString stringWithUTF8String:log->str] retain];
				[self setStatus:4];
			}
            if (TagIs("TUNET_LOGON_MONEY" ))  {
				NSLog(@"Money: %s\n",log->str);
				[money release];
				money = [[NSString stringWithUTF8String:log->str] retain];
				[self setStatus:4];
			}
            if (TagIs("TUNET_KEEPALIVE_ERROR" )) {
				bKeepAliveError = TRUE;
				NSBundle *mainBundle=[NSBundle mainBundle];
				NSString *growlTitle=[mainBundle localizedStringForKey:GROWL_ERROR_TITLE 
																 value:@""
																 table:nil];
				NSString *growlString=[mainBundle localizedStringForKey:GROWL_ERROR_CONTENT
																  value:@""
																  table:nil];
				[self growlAlert:growlString title:growlTitle];
			}
			
#undef TagIs
#undef StrIs
			
            if(bDot1xSuccess)
            {
                nDot1xRetryCount = 0;
            }
			
            if(bTunetSuccess)
            {
                nTunetRetryCount = 0;
            }
			
            if(bDot1xFailure && g_UserConfig.bUseDot1x)
            {
                dot1x_reset();
                g_DelayRetry = DELAY_RETRY_DOT1X;
                nRetryDelay = 5 + nDot1xRetryCount * 2;
                if(nRetryDelay >= 30) nRetryDelay = 30;
                nRetryDelay *= 1000;
                os_tick_set_delay(retry_timer, nRetryDelay);
                os_tick_clear(retry_timer);
            }
			
            if(bTunetFailure)
            {
                dot1x_reset();
                g_DelayRetry = DELAY_RETRY_TUNET;
                nRetryDelay = 120 + nTunetRetryCount * 60;
                if(nRetryDelay >= 5 * 60) nRetryDelay = 5 * 60;
                nRetryDelay *= 1000;
                os_tick_set_delay(retry_timer, nRetryDelay);
                os_tick_clear(retry_timer);
				
                if(nTunetRetryCount >= 10)
                {
                    tunet_reset();
                    g_Goal =  GOAL_NONE;
                }
            }
			
            if( (bNetworkError || bKeepAliveError) && g_Goal == GOAL_LOGIN)
            {
				NSLog(@"bNetworkError || bKeepAliveError) && g_Goal == GOAL_LOGIN");
                tunet_reset();
                dot1x_reset();
				
                if(g_UserConfig.bUseDot1x)
                {
                    nDot1xRetryCount = 0;
                    g_DelayRetry = DELAY_RETRY_DOT1X;
                    nRetryDelay = 5;
                }
                else
                {
                    nTunetRetryCount = 0;
                    g_DelayRetry = DELAY_RETRY_TUNET;
                    nRetryDelay = 1;
                }
				
                nRetryDelay *= 1000;
                os_tick_set_delay(retry_timer, nRetryDelay);
                os_tick_clear(retry_timer);
            }
			
            log = log_free(log);
            goto RefetchLog;
        }
		
		if (tunet_get_state()!=TUNET_STATE_KEEPALIVE) {
			deep_sleep=NO;
		}
		if (deep_sleep) {
			[condition lock];
/*			if ([condition waitUntilDate:[NSDate dateWithTimeIntervalSinceNow:2.0]]) {
				printf("signal caught.\n");
			}*/
			[condition waitUntilDate:[NSDate dateWithTimeIntervalSinceNow:2.0]];
			[condition unlock];
			
		}else {
			os_sleep(20);
		}
    }
	
    tunet_stop();
    if(g_UserConfig.bUseDot1x) dot1x_stop();
    tmpbuf[0] = DOT1X_STATE_NONE;
    tmpbuf[1] = DOT1X_STATE_NONE;
	
    g_logs = logs_append(g_logs, "MYTUNETSVC_STATE", NULL, tmpbuf, 2);

    while(1)
    {
        log = logs_fetch(g_logs, 0);
		
        if(log)
        {
            if(mytunetsvc_transmit_log)
                mytunetsvc_transmit_log(log);
			NSDateFormatter *dateFormatter=[[NSDateFormatter alloc] init];
			[dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
			[dateFormatter setFormatterBehavior:NSDateFormatterBehavior10_4];
			NSString *timeString=[dateFormatter stringFromDate:[NSDate date]];
			NSString *logString;
			if (log->str!=NULL) {
				NSStringEncoding enc = CFStringConvertEncodingToNSStringEncoding (kCFStringEncodingGB_18030_2000);
				logString=[[NSString stringWithCString:log->str encoding:enc] retain];
			}else {
				logString=[[NSString stringWithString:@""] retain];
			}
			NSString *string = [[NSString alloc] initWithFormat:@"%@: %s %@\n",timeString,log->tag, logString];
			[logString release];
			[self performSelectorOnMainThread:@selector(setConsoleString:)
								   withObject:string
								waitUntilDone:YES];
			[string release];
			[dateFormatter release];
            log = log_free(log);
			
        }
        else
        {
            break;
        }
    }
	
    retry_timer = os_tick_free(retry_timer);
    state_timer = os_tick_free(state_timer);
	NSNotificationCenter *nc=[NSNotificationCenter defaultCenter];
	[nc postNotificationName:@"connectionDidEnd" object:self];
	NSLog(@"Disconnected.\n");
	[pool release];

}
-(void)connectionDidEnd:(NSNotification *)aNote{
	[self setStatus:0];
	if (quitChoice) {
		[NSApp terminate:nil];
	}
	NSBundle *mainBundle=[NSBundle mainBundle];
	NSString *growlTitle=[mainBundle localizedStringForKey:GROWL_DISCONNECTED_TITLE 
													 value:@""
													 table:nil];
	NSString *growlString=[mainBundle localizedStringForKey:GROWL_DISCONNECTED_CONTENT
													  value:@""
													  table:nil];
	[self growlAlert:[NSString stringWithFormat:growlString,g_UserConfig.szUsername] title:growlTitle];

}
-(void)cleanUpService{
//	NSLog(@"clean up...\n");
	NSBundle *mainBundle=[NSBundle mainBundle];
	NSString *serviceStopped=[mainBundle localizedStringForKey:SERVICE_STOPPED
														 value:@""
														 table:nil];
	NSString *startServiceTitle=[mainBundle localizedStringForKey:START_SERVICE
															value:@""
															table:nil];
	NSMutableAttributedString *serviceString = [[NSMutableAttributedString alloc] initWithString:serviceStopped];
	[serviceString addAttribute:NSForegroundColorAttributeName
						  value:[NSColor redColor]
						  range:NSMakeRange(0, [serviceString length])];
	[serviceIndicator setAttributedStringValue:serviceString];
	[serviceString release];
	[startServiceButton setTitle:startServiceTitle];
	[startServiceButton setEnabled:YES];
	if ([[NSUserDefaults standardUserDefaults] boolForKey:ALLOW_REMOTE]==NO) {
		[startServiceButton setEnabled:NO];
	}
}
- (void)sheetDidEnd:(NSWindow *)sheet
		 returnCode:(int)returnCode
		contextInfo:(void *)contextInfo{
	//NSLog(@"returncode=%d\n",returnCode);
	if ([(NSString *)contextInfo isEqual:@"donateSheet"]) {
		if (returnCode==1) {
			[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:@"mailto:litunet@sina.com"]];
			
		}else {
			return;
		}
	}else if ([(NSString *)contextInfo isEqual:@"delete"]) {
		if (returnCode==1) {
			return;
		}
		int i;
		NSUserDefaults *defaults=[NSUserDefaults standardUserDefaults];
		if (selectedToolbarItem==0) {
			[defaults removeObjectForKey:ACCOUNT1_NAME];
			[defaults removeObjectForKey:ACCOUNT1_PASSWORD];
			[defaults removeObjectForKey:ACCOUNT1_ADAPTER];
			[defaults removeObjectForKey:ACCOUNT1_USEDOT1X];
			[defaults removeObjectForKey:ACCOUNT1_LIMITATION];
			[defaults performSelectorOnMainThread:@selector(synchronize)
									   withObject:nil 
									waitUntilDone:YES];
			[account1 performSelectorOnMainThread:@selector(setTitle:) 
									   withObject:emptyString
									waitUntilDone:YES];
			[self performSelectorOnMainThread:@selector(setAccountStatus:) 
								   withObject:[NSNumber numberWithInt:1]
								waitUntilDone:YES];
			if ([[defaults objectForKey:ACCOUNT2_NAME] isEqual:@""]) {
				[self performSelectorOnMainThread:@selector(setAccountStatus:) 
									   withObject:[NSNumber numberWithInt:6] 
									waitUntilDone:YES];
				if (statusTitle==0) {
					[self performSelectorOnMainThread:@selector(setConnectItemEnabled:) 
										   withObject:[NSNumber numberWithInt:0] 
										waitUntilDone:YES];
				}
				
			}else {
				[self performSelectorOnMainThread:@selector(setAccountStatus:) 
									   withObject:[NSNumber numberWithInt:5] 
									waitUntilDone:YES];
			}
		}else {
			[defaults removeObjectForKey:ACCOUNT2_NAME];
			[defaults removeObjectForKey:ACCOUNT2_PASSWORD];
			[defaults removeObjectForKey:ACCOUNT2_ADAPTER];
			[defaults removeObjectForKey:ACCOUNT2_USEDOT1X];
			[defaults removeObjectForKey:ACCOUNT2_LIMITATION];
			[defaults performSelectorOnMainThread:@selector(synchronize)
									   withObject:nil 
									waitUntilDone:YES];
			[account2 performSelectorOnMainThread:@selector(setTitle:) 
									   withObject:emptyString
									waitUntilDone:YES];
			[self performSelectorOnMainThread:@selector(setAccountStatus:) 
								   withObject:[NSNumber numberWithInt:3]
								waitUntilDone:YES];
			if ([[defaults objectForKey:ACCOUNT1_NAME] isEqual:@""]) {
				[self performSelectorOnMainThread:@selector(setAccountStatus:) 
									   withObject:[NSNumber numberWithInt:6] 
									waitUntilDone:YES];
				if (statusTitle==0) {
					[self performSelectorOnMainThread:@selector(setConnectItemEnabled:) 
										   withObject:[NSNumber numberWithInt:0] 
										waitUntilDone:YES];
				}
			}else {
				[self performSelectorOnMainThread:@selector(setAccountStatus:) 
									   withObject:[NSNumber numberWithInt:4] 
									waitUntilDone:YES];
			}
		}
		[usernameField setStringValue:@""];
		[passwordField setStringValue:@""];
		[type selectItemAtIndex:0];
		for(i=0;i<[interfaces numberOfItems];i++){
			if ([(NSString*)SCNetworkInterfaceGetBSDName((SCNetworkInterfaceRef)[networkInterfaces objectAtIndex:i]) isEqual:@"en0"]) {
				[interfaces selectItemAtIndex:i];
				break;
			}
		}
		[useDot1x setState:NSOffState];
		[deleteButton setEnabled:NO];
	}else if ([(NSString *)contextInfo isEqual:@"remoteSettingsComplete"]) {
		return;
	}else if ([(NSString *)contextInfo isEqual:@"gpl"]) {
		return;
	}else {
		if (returnCode==1) {
			[self saveConfig:sheet];
		}
		[self setSaveButtonEnabled:NO];
		[sheet close];
		if ([(NSString *)contextInfo isEqual:@"console"]) {
			[self switchToConsole];
		}else if ([(NSString *)contextInfo isEqual:@"account1"]) {
			[self switchToAccount1];
		}else if([(NSString *)contextInfo isEqual:@"account2"]){
			[self switchToAccount2];
		}else if ([(NSString *)contextInfo isEqual:@"options"]) {
			[self switchToOptions];
		}else if([(NSString *)contextInfo isEqual:@"close"]){
			[mainWindow orderOut:self];
			selectedToolbarItem=-1;
		}

	}	
}
-(IBAction)toggleAutoStart:(id)sender{
	if ([sender state]==NSOnState) {
		if ([UKLoginItemRegistry indexForLoginItemWithPath:[[NSBundle mainBundle] bundlePath]]) {
			return;
		}else {
			
			if (![UKLoginItemRegistry addLoginItemWithPath:[[NSBundle mainBundle] bundlePath]
													hideIt:NO]) {
				[sender setState:NSOffState];
			}
		}

	}else {
		if ([UKLoginItemRegistry indexForLoginItemWithPath:[[NSBundle mainBundle] bundlePath]]<0) {
			return;
		}else {
			if (![UKLoginItemRegistry removeLoginItemWithPath:[[NSBundle mainBundle] bundlePath]]) {
				[sender setState:NSOnState];
			}
		}

	}

}
-(IBAction)saveConfig:(id)sender{
	BYTE md5[16];
    CHAR pwd[200];
    CHAR encoded[100];
	NSUserDefaults *defaults=[NSUserDefaults standardUserDefaults];
	
	MD5Buffer((char *)[[passwordField stringValue] UTF8String], strlen((char *)[[passwordField stringValue] UTF8String]), md5);
	buf2hex(md5, 16, pwd);
	
    EncodePasswordByUsername((char *)[[usernameField stringValue] UTF8String], pwd, encoded);
	if (selectedToolbarItem==0) {
		[defaults setObject:[usernameField stringValue] forKey:ACCOUNT1_NAME];
		[defaults setObject:[NSString stringWithUTF8String:encoded] forKey:ACCOUNT1_PASSWORD];
		[defaults setObject:(NSString*)SCNetworkInterfaceGetBSDName((SCNetworkInterfaceRef)[networkInterfaces objectAtIndex:[interfaces indexOfSelectedItem]])
					 forKey:ACCOUNT1_ADAPTER];
		[defaults setObject:[NSString stringWithFormat:@"%d", [type indexOfSelectedItem]] forKey:ACCOUNT1_LIMITATION];
		if ([useDot1x state]==NSOnState) {
			[defaults setObject:@"1" forKey:ACCOUNT1_USEDOT1X];
		}else {
			[defaults setObject:@"0" forKey:ACCOUNT1_USEDOT1X];
		}

	}else {
		[defaults setObject:[usernameField stringValue] forKey:ACCOUNT2_NAME];
		[defaults setObject:[NSString stringWithUTF8String:encoded] forKey:ACCOUNT2_PASSWORD];
		[defaults setObject:(NSString*)SCNetworkInterfaceGetBSDName((SCNetworkInterfaceRef)[networkInterfaces objectAtIndex:[interfaces indexOfSelectedItem]])
					 forKey:ACCOUNT2_ADAPTER];
		[defaults setObject:[NSString stringWithFormat:@"%d", [type indexOfSelectedItem]] forKey:ACCOUNT2_LIMITATION];
		if ([useDot1x state]==NSOnState) {
			[defaults setObject:@"1" forKey:ACCOUNT2_USEDOT1X];
		}else {
			[defaults setObject:@"0" forKey:ACCOUNT2_USEDOT1X];
		}
		
	}
	[defaults performSelectorOnMainThread:@selector(synchronize)
							   withObject:nil 
							waitUntilDone:YES];
    
	[self setSaveButtonEnabled:NO];
	[passwordField performSelectorOnMainThread:@selector(setStringValue:) 
									withObject:@"" 
								 waitUntilDone:YES];
	
	if (selectedToolbarItem==0) {
		[account1 performSelectorOnMainThread:@selector(setTitle:) 
								   withObject:[defaults objectForKey:ACCOUNT1_NAME ]
								waitUntilDone:YES];
		if ([account1 isEnabled]==NO) {
			[self performSelectorOnMainThread:@selector(setAccountStatus:) 
								   withObject:[NSNumber numberWithInt:0]
								waitUntilDone:YES];
		}
		if ([[defaults objectForKey:ACCOUNT2_NAME] isEqual:@""]) {
			[self performSelectorOnMainThread:@selector(setAccountStatus:)
								   withObject:[NSNumber numberWithInt:4]
								waitUntilDone:YES];
		}
	}else {
		[account2 performSelectorOnMainThread:@selector(setTitle:) 
								   withObject:[defaults objectForKey:ACCOUNT2_NAME ]
								waitUntilDone:YES];
		if ([account2 isEnabled]==NO) {
			[self performSelectorOnMainThread:@selector(setAccountStatus:) 
								   withObject:[NSNumber numberWithInt:2]
								waitUntilDone:YES];
		}
		if ([[defaults objectForKey:ACCOUNT1_NAME] isEqual:@""]) {
			[self performSelectorOnMainThread:@selector(setAccountStatus:)
								   withObject:[NSNumber numberWithInt:5]
								waitUntilDone:YES];
		}
	}
	if ([connectItem isEnabled]==NO) {
		[self performSelectorOnMainThread:@selector(setConnectItemEnabled:) 
							   withObject:[NSNumber numberWithInt:1] 
							waitUntilDone:YES];
	}
	[deleteButton setEnabled:YES];
}
-(IBAction)deleteAccount:(id)sender{
	NSBundle *mainBundle=[NSBundle mainBundle];
	NSString *title=[mainBundle localizedStringForKey:DELETE_CONFIRM_TITLE
												value:@""
												table:nil];
	NSString *button1=[mainBundle localizedStringForKey:DELETE_CONFIRM_BUTTON1
												  value:@""
												  table:nil];
	NSString *button2=[mainBundle localizedStringForKey:DELETE_CONFIRM_BUTTON2
												  value:@""
												  table:nil];
	NSString *content=[mainBundle localizedStringForKey:DELETE_CONFIRM_CONTENT
												  value:@""
												  table:nil];
	NSString *chosenAccount;
	NSUserDefaults *defaults=[NSUserDefaults standardUserDefaults];
	if (selectedToolbarItem==0) {
		chosenAccount=[defaults objectForKey:ACCOUNT1_NAME];
	}else {
		chosenAccount=[defaults objectForKey:ACCOUNT2_NAME];
	}

	NSBeginAlertSheet(title,
					  button1,
					  button2,
					  nil,
					  mainWindow,
					  self,
					  @selector(sheetDidEnd:returnCode:contextInfo:),
					  nil,
					  @"delete",
					 [NSString stringWithFormat:content,chosenAccount]);
}
-(IBAction)quitApp:(id)sender{
	[[NSUserDefaults standardUserDefaults] synchronize];
	[NSApp terminate:nil];
}

-(IBAction)showAccountWindow:(id)sender{
	[self switchToAccount1];
	NSToolbar *tb=[mainWindow toolbar];
	[tb setSelectedItemIdentifier:@"Account 1"];
	[mainWindow makeKeyAndOrderFront:self];
	[NSApp activateIgnoringOtherApps:YES];
}
-(IBAction)showOptions:(id)sender{
	[self switchToOptions];
	NSToolbar *tb=[mainWindow toolbar];
	[tb setSelectedItemIdentifier:@"Options"];
	[mainWindow makeKeyAndOrderFront:self];
	[NSApp activateIgnoringOtherApps:YES];
}
-(IBAction)showConsole:(id)sender{
	[self switchToConsole];
	NSToolbar *tb=[mainWindow toolbar];
	[tb setSelectedItemIdentifier:@"Console"];
	[mainWindow makeKeyAndOrderFront:self];
	[NSApp activateIgnoringOtherApps:YES];
}
-(IBAction)showAboutWindow:(id)sender{
	if ([[appName stringValue] isEqual:@""]) {
		NSBundle *mainBundle=[NSBundle mainBundle];
		NSString *creditsPath=[mainBundle pathForResource:@"Credits"
												   ofType:@"rtf"];
		NSDictionary *infoDict=[mainBundle infoDictionary];
		NSMutableAttributedString *appNameString=[[NSMutableAttributedString alloc] 
												  initWithString:[infoDict objectForKey:@"CFBundleName"]];
		[appNameString addAttribute:NSFontAttributeName
							  value:[NSFont boldSystemFontOfSize:36]
							  range:NSMakeRange(0, [appNameString length])];
		[appNameString setAlignment:NSCenterTextAlignment
							  range:NSMakeRange(0, [appNameString length])];
		[appName setAttributedStringValue:appNameString];
		[aboutWindow setTitle:[NSString stringWithFormat:@"About: %@",[appNameString string]]];
		NSMutableAttributedString *appVersionString=[[NSMutableAttributedString alloc]
													 initWithString:[NSString stringWithFormat:@"%@ (%@)",
																	 [infoDict objectForKey:@"CFBundleShortVersionString"],
													 [infoDict objectForKey:@"CFBundleVersion"]]];
		[appVersionString addAttribute:NSFontAttributeName
								  value:[NSFont userFontOfSize:18]
								  range:NSMakeRange(0, [appVersionString length])];
		[appVersionString addAttribute:NSForegroundColorAttributeName
								  value:[NSColor grayColor]
								  range:NSMakeRange(0, [appVersionString length])];
		[appVersionString setAlignment:NSCenterTextAlignment
								 range:NSMakeRange(0, [appVersionString length])];
		[appVersion setAttributedStringValue:appVersionString];
		NSAttributedString *creditsString=[[NSAttributedString alloc] initWithPath:creditsPath
																documentAttributes:nil];
		[appCredits replaceCharactersInRange:NSMakeRange(0, 0)
									 withRTF:[creditsString RTFFromRange:NSMakeRange(0, [creditsString length])
													  documentAttributes:nil]];
		int i;
		maxScrollHeight=0;
		for(i=0;i<[creditsString length];i++){
			if ([[creditsString string] characterAtIndex:i]=='\n') {
				maxScrollHeight+=12;
			}
		}
		maxScrollHeight=maxScrollHeight-[appCredits frame].size.height;
		NSString *iconPath=[mainBundle pathForResource:@"icon"
												ofType:@"png"];
		NSImage *iconImage=[[NSImage alloc] initWithContentsOfFile:iconPath];

		[appIcon setImage:iconImage];
		[aboutWindow setExcludedFromWindowsMenu:YES];
		[aboutWindow center];
		[iconImage release];
		[appNameString release];
		[appVersionString release];
		[creditsString release];
	}
	if (![aboutWindow isVisible]) {
		currentPosition = 0.0;
		restartAtTop = NO;
		startTime = [NSDate timeIntervalSinceReferenceDate] + 0.0;
		[appCredits scrollPoint:NSMakePoint(0, 0)];
		
	}
	[aboutWindow setBackgroundColor:[NSColor colorWithCalibratedRed:255.0
															  green:255.0
															   blue:255.0
															  alpha:1.0]];
	[aboutWindow makeKeyAndOrderFront:self];
	[NSApp activateIgnoringOtherApps:YES];
}
- (void)windowDidBecomeKey:(id)sender
{
	if ([[sender object] isEqual:aboutWindow]) {
		scrollTimer = [NSTimer scheduledTimerWithTimeInterval:0.02
													   target:self 
													 selector:@selector(scrollCredits:) 
													 userInfo:nil 
													  repeats:YES];
	}
    
}
- (void)windowDidResignKey:(id)sender
{
	if ([[sender object] isEqual:aboutWindow]) {
//		NSLog(@"Scrolling stopped.\n");
			[scrollTimer invalidate];		
	}
    
}
-(void)scrollCredits:(NSTimer *)timer{
	if ([NSDate timeIntervalSinceReferenceDate] >= startTime) {
		
		if (restartAtTop) {
			startTime=[NSDate timeIntervalSinceReferenceDate]+0.5;
			restartAtTop=NO;
			[appCredits scrollPoint:NSMakePoint(0, 0)];
			return;
		}
		if (currentPosition>=maxScrollHeight) {
			startTime=[NSDate timeIntervalSinceReferenceDate]+0.5;
			restartAtTop=YES;
			currentPosition=0.0;
		} else {
			[appCredits scrollPoint:NSMakePoint(0, currentPosition)];
			currentPosition += 0.3;
		}

	}
}
-(void)setStatus:(NSInteger)status{
	if (status==0) {
		NSBundle *mainBundle=[NSBundle mainBundle];
		NSString *connectMenuImagePath=[mainBundle pathForResource:@"Connect_menu" ofType:@"png"];
		NSImage *connectMenuImage=[[NSImage alloc] initWithContentsOfFile:connectMenuImagePath];
		disconnectedString = [mainBundle localizedStringForKey:DISCONNECTED_STRING 
													value:@""
													table:nil];
		connectString = [mainBundle localizedStringForKey:CONNECT_STRING 
													 value:@""
													 table:nil];
		[connectionStatus performSelectorOnMainThread:@selector(setTitle:) 
										   withObject:disconnectedString 
										waitUntilDone:YES];
		[statusItem performSelectorOnMainThread:@selector(setToolTip:)
									 withObject:[NSString stringWithFormat:@"Litunet: %@.",disconnectedString]
								  waitUntilDone:YES];
		[statusItem performSelectorOnMainThread:@selector(setImage:) 
									 withObject:image_ 
								  waitUntilDone:YES];
		[connectionStatus performSelectorOnMainThread:@selector(setImage:) 
										   withObject:disconnectedImage
										waitUntilDone:YES];
		[connectItem performSelectorOnMainThread:@selector(setTitle:) 
									  withObject:connectString
								   waitUntilDone:YES];
		[connectItem performSelectorOnMainThread:@selector(setImage:)
									  withObject:connectMenuImage
								   waitUntilDone:YES];
		[self performSelectorOnMainThread:@selector(setConnectItemEnabled:) 
							   withObject:[NSNumber numberWithInt:1] 
							waitUntilDone:YES];
		NSUserDefaults *defaults=[NSUserDefaults standardUserDefaults];
		if ([[defaults objectForKey:ACCOUNT1_NAME] isEqual:@""]&&[[defaults objectForKey:ACCOUNT2_NAME] isEqual:@""]) {
			[self performSelectorOnMainThread:@selector(setConnectItemEnabled:) 
								   withObject:[NSNumber numberWithInt:0]
								waitUntilDone:YES];
		}
		[connectMenuImage release];
		statusTitle=0;

	} else if (status==1) {
		NSBundle *mainBundle=[NSBundle mainBundle];
		NSString *disconnectMenuImagePath=[mainBundle pathForResource:@"Disconnect_menu" ofType:@"png"];
		NSImage *disconnectMenuImage=[[NSImage alloc] initWithContentsOfFile:disconnectMenuImagePath];
		disconnectString = [mainBundle localizedStringForKey:DISCONNECT_STRING 
														 value:@""
														 table:nil];
		connectingString = [mainBundle localizedStringForKey:CONNECTING_STRING 
													value:@""
													table:nil];

		[connectionStatus performSelectorOnMainThread:@selector(setTitle:) 
										   withObject:connectingString 
										waitUntilDone:YES];
		[connectItem performSelectorOnMainThread:@selector(setTitle:) 
									 withObject:disconnectString
								  waitUntilDone:YES];
		[connectItem performSelectorOnMainThread:@selector(setImage:)
									  withObject:disconnectMenuImage
								   waitUntilDone:YES];
		[statusItem performSelectorOnMainThread:@selector(setToolTip:)
									 withObject:[NSString stringWithFormat:@"Litunet: %@",connectingString]
								  waitUntilDone:YES];
		[statusItem performSelectorOnMainThread:@selector(setImage:) 
									 withObject:image_ 
								  waitUntilDone:YES];
		[connectionStatus performSelectorOnMainThread:@selector(setImage:) 
										   withObject:connectingImage
										waitUntilDone:YES];
		[disconnectMenuImage release];
		statusTitle=1;
	} else if (status==2) {
		NSBundle *mainBundle=[NSBundle mainBundle];
		
		connectedString = [mainBundle localizedStringForKey:CONNECTED_STRING 
														 value:@""
														 table:nil];

		[connectionStatus performSelectorOnMainThread:@selector(setTitle:) 
									 withObject:connectedString 
								  waitUntilDone:YES];
		[statusItem performSelectorOnMainThread:@selector(setToolTip:)
									 withObject:[NSString stringWithFormat:@"Litunet: %@ (%s).",connectedString,g_UserConfig.szUsername]
								  waitUntilDone:YES];
		[statusItem performSelectorOnMainThread:@selector(setImage:) 
									 withObject:image_0 
								  waitUntilDone:YES];
		[connectionStatus performSelectorOnMainThread:@selector(setImage:) 
										   withObject:connectedImage
										waitUntilDone:YES];
		NSString *growlTitle=[mainBundle localizedStringForKey:GROWL_CONNECTED_TITLE 
														 value:@""
														 table:nil];
		NSString *growlString=[mainBundle localizedStringForKey:GROWL_CONNECTED_CONTENT
														  value:@""
														  table:nil];
		NSString *alertString=[NSString stringWithFormat:growlString,g_UserConfig.szUsername];
		[self growlAlert:alertString title:growlTitle];
		statusTitle=2;
	} else if(status==3){
		NSBundle *mainBundle=[NSBundle mainBundle];
		NSString *connectMenuImagePath=[mainBundle pathForResource:@"Connect_menu" ofType:@"png"];
		NSImage *connectMenuImage=[[NSImage alloc] initWithContentsOfFile:connectMenuImagePath];
		disconnectingString = [mainBundle localizedStringForKey:DISCONNECTING_STRING 
														 value:@""
														 table:nil];
		connectString = [mainBundle localizedStringForKey:CONNECT_STRING 
													value:@""
													table:nil];

		[connectionStatus performSelectorOnMainThread:@selector(setTitle:) 
									 withObject:disconnectingString 
								  waitUntilDone:YES];
		[connectItem performSelectorOnMainThread:@selector(setTitle:) 
									 withObject:connectString 
								  waitUntilDone:YES];
		[connectItem performSelectorOnMainThread:@selector(setImage:)
									  withObject:connectMenuImage
								   waitUntilDone:YES];
		[statusItem performSelectorOnMainThread:@selector(setToolTip:)
									 withObject:[NSString stringWithFormat:@"Litunet: %@.",disconnectingString]
								  waitUntilDone:YES];
		[statusItem performSelectorOnMainThread:@selector(setImage:) 
									 withObject:image_ 
								  waitUntilDone:YES];
		[connectionStatus performSelectorOnMainThread:@selector(setImage:) 
										   withObject:connectingImage
										waitUntilDone:YES];
		[self performSelectorOnMainThread:@selector(setConnectItemEnabled:) 
							   withObject:[NSNumber numberWithInt:0] 
							waitUntilDone:YES];
		[connectMenuImage release];
		statusTitle=3;
		
	}else {
		NSBundle *mainBundle=[NSBundle mainBundle];
		switch (statusTitle) {
			case 0:
				disconnectedString = [mainBundle localizedStringForKey:DISCONNECTED_STRING 
															value:@""
															table:nil];
				[connectionStatus performSelectorOnMainThread:@selector(setTitle:) 
											 withObject:[NSString stringWithFormat:@"%@ (¥%@)",disconnectedString,money] 
										  waitUntilDone:YES];
				[statusItem performSelectorOnMainThread:@selector(setToolTip:)
											 withObject:[NSString stringWithFormat:@"Litunet: %@ (¥%@).",disconnectedString,money]
										  waitUntilDone:YES];
				break;
			case 1:
				connectingString = [mainBundle localizedStringForKey:CONNECTING_STRING 
																 value:@""
																 table:nil];
				[connectionStatus performSelectorOnMainThread:@selector(setTitle:) 
												   withObject:[NSString stringWithFormat:@"%@ (¥%@)",connectingString,money] 
												waitUntilDone:YES];
				[statusItem performSelectorOnMainThread:@selector(setToolTip:)
											 withObject:[NSString stringWithFormat:@"Litunet: %@ (¥%@)",connectingString,money]
										  waitUntilDone:YES];
				break;
			case 2:
				connectedString = [mainBundle localizedStringForKey:CONNECTED_STRING 
																 value:@""
																 table:nil];
				[connectionStatus performSelectorOnMainThread:@selector(setTitle:) 
												   withObject:[NSString stringWithFormat:@"%@ (¥%@)",connectedString,money] 
												waitUntilDone:YES];
				[statusItem performSelectorOnMainThread:@selector(setToolTip:)
											 withObject:[NSString stringWithFormat:@"Litunet: %@ (%s, ¥%@).",connectedString,g_UserConfig.szUsername,money]
										  waitUntilDone:YES];
				break;
			default:
				disconnectingString = [mainBundle localizedStringForKey:DISCONNECTING_STRING 
																 value:@""
																 table:nil];
				[connectionStatus performSelectorOnMainThread:@selector(setTitle:) 
												   withObject:[NSString stringWithFormat:@"%@ (¥%@)",disconnectingString,money] 
												waitUntilDone:YES];
				[statusItem performSelectorOnMainThread:@selector(setToolTip:)
											 withObject:[NSString stringWithFormat:@"Litunet: %@ (¥%@)",disconnectingString,money]
										  waitUntilDone:YES];
				break;
		}


	}


}

-(BOOL)windowShouldClose:(id)sender{
	if ([sender isEqual:mainWindow]) {
		if ([saveButton isEnabled]) {
			NSBundle *mainBundle=[NSBundle mainBundle];
			NSString *chosenAccount;
			NSUserDefaults *defaults=[NSUserDefaults standardUserDefaults];
			if (selectedToolbarItem==0) {
				chosenAccount=[defaults objectForKey:ACCOUNT1_NAME];
			}else {
				chosenAccount=[defaults objectForKey:ACCOUNT2_NAME];
			}
			NSString *title=[mainBundle localizedStringForKey:SAVE_PROMOT_TITLE
														value:@""
														table:nil];
			NSString *button1=[mainBundle localizedStringForKey:SAVE_PROMOT_BUTTON1 
														  value:@""
														  table:nil];
			NSString *button2=[mainBundle localizedStringForKey:SAVE_PROMOT_BUTTON2
														  value:@""
														  table:nil];
			if ([chosenAccount isEqual:@""]) {
				NSString *content=[mainBundle localizedStringForKey:SAVE_PROMOT_CONTENT_ALERT
															  value:@""
															  table:nil];
				NSBeginAlertSheet(title, 
								  button1, 
								  button2,
								  nil,
								  mainWindow,
								  self,
								  @selector(sheetDidEnd:returnCode:contextInfo:),
								  nil,
								  @"close",
								  content);
			}else {
				NSString *content=[mainBundle localizedStringForKey:SAVE_PROMOT_CONTENT
															  value:@""
															  table:nil];
				NSBeginAlertSheet(title, 
								  button1, 
								  button2,
								  nil,
								  mainWindow,
								  self,
								  @selector(sheetDidEnd:returnCode:contextInfo:),
								  nil,
								  @"close",
								  [NSString stringWithFormat:content,chosenAccount]);
			}
		}else {
			[mainWindow orderOut:self];
			selectedToolbarItem=-1;
		}
	}else if ([sender isEqual:limoteWindow]) {
		[limoteWindow orderOut:self];
	}else{
		[aboutWindow orderOut:self];		
	}
	return NO;
	
}
-(void)setSaveButtonEnabled:(BOOL)enable{
	[saveButton setEnabled:enable];
	if (enable==YES) {
		[mainWindow setDocumentEdited:YES];
	}else {
		[mainWindow setDocumentEdited:NO];
	}

}
-(IBAction)deviceChanged:(id)sender{
	if ([[usernameField stringValue] isEqual:@""] || [[passwordField stringValue] isEqual:@""]) {
		[self setSaveButtonEnabled:NO];
		return;
	}
	[self setSaveButtonEnabled:YES];
}
-(IBAction)typeChanged:(id)sender{
	if ([[usernameField stringValue] isEqual:@""] || [[passwordField stringValue] isEqual:@""]) {
		[self setSaveButtonEnabled:NO];
		return;
	}
	[self setSaveButtonEnabled:YES];
}
-(IBAction)portAuthorizationChanged:(id)sender{
	if ([[usernameField stringValue] isEqual:@""] || [[passwordField stringValue] isEqual:@""]) {
		[self setSaveButtonEnabled:NO];
		return;
	}
	[self setSaveButtonEnabled:YES];
}
- (void)controlTextDidChange:(NSNotification *)aNotification{
	if ([[aNotification object] isEqual:usernameField] || [[aNotification object] isEqual:passwordField]) {
		if ([[usernameField stringValue] isEqual:@""] || [[passwordField stringValue] isEqual:@""]) {
			[self setSaveButtonEnabled:NO];
			return;
		}
		[self setSaveButtonEnabled:YES];
	}else if ([[aNotification object] isEqual:remotePasswordField]||[[aNotification object] isEqual:portNumberField]) {
		if ([[remotePasswordField stringValue]  isEqual:@""]) {
			[remoteSaveButton setEnabled:NO];
			return;
		}
		if (![[portNumberField stringValue] isEqual:@""]) {
			int i;
			for(i=0;i<[[portNumberField stringValue] length];i++){
				char buffer=[[portNumberField stringValue] characterAtIndex:i];
				if (buffer<'0'||buffer>'9') {
					[remoteSaveButton setEnabled:NO];
					return;
				}
			}
			if ([[portNumberField stringValue] intValue]<=5000||[[portNumberField stringValue] intValue]>65535) {
				[remoteSaveButton setEnabled:NO];
				return;
			}
		}
		[remoteSaveButton setEnabled:YES];
	}else if ([[aNotification object] isEqual:remoteControlPass] || [[aNotification object] isEqual:remoteServerIP] ||[[aNotification object] isEqual:remotePortNumberField] ) {
		NSString *ipString = [remoteServerIP stringValue];
		int sum=0,sumbuffer,i=0,flag=0;
		int numberIdx=0,dotCount=0;
		char buffer;
		for(i=0;i<[ipString length];i++){
			buffer=[ipString characterAtIndex:i];
			if (buffer!='.'&&!(buffer>='0'&&buffer<='9')) {
				flag=1;
				break;
			}
			if (buffer=='.') {
				dotCount++;
				if (dotCount>=4) {
					flag=1;
					break;
				}
				if (numberIdx>3||numberIdx==0) {
					flag=1;
					break;
				}
				if (numberIdx==2) {
					sum=sum/10;
				}else if (numberIdx==1) {
					sum=sum/100;
				}
				if (sum>=256) {
					flag=1;
					break;
				}
				sum=0;
				numberIdx=0;
			}else {
				numberIdx++;
				if (numberIdx==1) {
					sum+=(buffer-'0')*100;
				}else if (numberIdx==2) {
					if ([ipString characterAtIndex:i-1]=='0') {
						flag=1;
						break;
					}
					sum+=(buffer-'0')*10;
				}else if (numberIdx==3) {
					sum+=(buffer-'0');
				}else{
					flag=1;
					break;
				}
				sumbuffer=sum;
				if (numberIdx==2) {
					sumbuffer=sumbuffer/10;
				}else if (numberIdx==1) {
					sumbuffer=sumbuffer/100;
				}
				if (sumbuffer>=256) {
					flag=1;
					break;
				}
			}
		}
		if (dotCount!=3) {
			flag=1;
		}
		if ([ipString characterAtIndex:[ipString length]-1]=='.') {
			flag=1;
		}
		if (![[remotePortNumberField stringValue] isEqual:@""]) {
			int i;
			for(i=0;i<[[remotePortNumberField stringValue] length];i++){
				char buffer=[[remotePortNumberField stringValue] characterAtIndex:i];
				if (buffer<'0'||buffer>'9') {
					flag=1;
					break;
				}
			}
			if ([[remotePortNumberField stringValue] intValue]<=5000||[[remotePortNumberField stringValue] intValue]>65535) {
				flag=1;
			}
		}
		if (flag) {
			[self setEnableThreeButtons:[NSNumber numberWithInt:0]];
		}else {
			if ([[remoteControlPass stringValue] isEqual:@""]) {
				[self setEnableThreeButtons:[NSNumber numberWithInt:0]];
			}else {
				[self setEnableThreeButtons:[NSNumber numberWithInt:1]];
			}
		}

	}
}
-(void)setConnectItemEnabled:(NSNumber *)aNumber{
	if ([aNumber intValue]==0) {
		[connectItem setEnabled:NO];
	}else {
		[connectItem setEnabled:YES];
	}

}
-(IBAction)chooseAccount:(id)sender{
	NSUserDefaults *userDefaults=[NSUserDefaults standardUserDefaults];
	if ([sender isEqual:account1]) {
		if ([[userDefaults objectForKey:ACCOUNT2_NAME] isEqual:@""]) {
			return;
		}
		[self performSelectorOnMainThread:@selector(setAccountStatus:) 
							   withObject:[NSNumber numberWithInt:4]
							waitUntilDone:YES];
	}else {
		if ([[userDefaults objectForKey:ACCOUNT1_NAME] isEqual:@""]) {
			return;
		}
		[self performSelectorOnMainThread:@selector(setAccountStatus:)
							   withObject:[NSNumber numberWithInt:5]
							waitUntilDone:YES];
	}

}
-(void)setAccountStatus:(NSNumber *)aNumber{
	NSUserDefaults *defaults=[NSUserDefaults standardUserDefaults];
	switch ([aNumber intValue]) {
		case 0:
			[account1 setEnabled:YES];
			break;
		case 1:
			[account1 setEnabled:NO];
			break;
		case 2:
			[account2 setEnabled:YES];
			break;
		case 3:
			[account2 setEnabled:NO];
			break;
		case 4:
			[account1 setState:NSOnState];
			[account2 setState:NSOffState];
			[defaults setObject:@"0" forKey:ACCOUNT_CHOICE];
			[defaults performSelectorOnMainThread:@selector(synchronize)
									   withObject:nil 
									waitUntilDone:YES];
			break;
		case 5:
			[account1 setState:NSOffState];
			[account2 setState:NSOnState];
			[defaults setObject:@"1" forKey:ACCOUNT_CHOICE];
			[defaults performSelectorOnMainThread:@selector(synchronize)
									   withObject:nil 
									waitUntilDone:YES];
			break;
		default:
			[account1 setState:NSOffState];
			[account2 setState:NSOffState];
			[defaults setObject:@"0" forKey:ACCOUNT_CHOICE];
			[defaults performSelectorOnMainThread:@selector(synchronize)
									   withObject:nil 
									waitUntilDone:YES];
			break;
	}
}

-(void)setConsoleString:(NSString *)aString{
	[consoleLock lock];
	NSTextStorage *ts=[[consoleContent textStorage] retain];
	if (consoleCount>=300) {
		NSRange aRange;
		aRange=[[ts string] rangeOfString:@"\n"];
		if (aRange.location!=NSNotFound) {
			[ts replaceCharactersInRange:NSMakeRange(0, [ts length])
							  withString:[[ts string] substringFromIndex:aRange.location+1]];
		}
		[ts replaceCharactersInRange:NSMakeRange([ts length], 0) withString:aString];
		[ts setFont:[NSFont fontWithName:@"Monaco"
									size:10]];
		[ts setForegroundColor:[NSColor whiteColor]];
		[clearButton setEnabled:YES];
	}else {
		consoleCount++;
		[ts replaceCharactersInRange:NSMakeRange([ts length], 0) withString:aString];
		[ts setFont:[NSFont fontWithName:@"Monaco"
									size:10]];
		[ts setForegroundColor:[NSColor whiteColor]];
		[clearButton setEnabled:YES];
	}
	[ts release];
	[consoleLock unlock];
}
-(IBAction)clearConsole:(id)sender{
	[consoleLock lock];
	[consoleContent setString:@""];
	consoleCount=0;
	[clearButton setEnabled:NO];
	[consoleLock unlock];
}
-(IBAction)closeAbout:(id)sender{
	[aboutWindow orderOut:self];
}
-(IBAction)showGPL:(id)sender{
	[NSApp beginSheet:gplWindow
	   modalForWindow:aboutWindow
		modalDelegate:self 
	   didEndSelector:@selector(sheetDidEnd:returnCode:contextInfo:) 
		  contextInfo:@"gpl"];
	
}
-(IBAction)agreeGPL:(id)sender{
	[NSApp endSheet:gplWindow];
	[gplWindow orderOut:sender];
}
-(IBAction)donate:(id)sender{
	NSBundle *mainBundle=[NSBundle mainBundle];
	NSString *title=[mainBundle localizedStringForKey:DONATE_CONFIRM_TITLE
												value:@""
												table:nil];
	NSString *button1=[mainBundle localizedStringForKey:DONATE_CONFIRM_BUTTON1
												  value:@""
												  table:nil];
	NSString *button2=[mainBundle localizedStringForKey:DONATE_CONFIRM_BUTTON2
												  value:@""
												  table:nil];
	NSString *content=[mainBundle localizedStringForKey:DONATE_CONFIRM_CONTENT
												  value:@""
												  table:nil];
	NSBeginAlertSheet(title,
					  button1,
					  button2,
					  nil,
					  aboutWindow,
					  self,
					  @selector(sheetDidEnd:returnCode:contextInfo:),
					  nil,
					  @"donateSheet",
					  content);
}
-(IBAction)goToWebsite:(id)sender{
	[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:@"http://blog.sina.com.cn/litunet"]];
}
-(IBAction)alowRemoteControl:(id)sender{
	NSUserDefaults *defaults=[NSUserDefaults standardUserDefaults];
	if ([sender state]==NSOnState) {
		[remotePasswordField setStringValue:@""];
		[remoteSaveButton setEnabled:NO];
		[NSApp beginSheet:remoteSettingWindow
		   modalForWindow:mainWindow
			modalDelegate:self
		   didEndSelector:@selector(sheetDidEnd:returnCode:contextInfo:)
			  contextInfo:@"remoteSettingsComplete"];
		[remoteSettingWindow makeFirstResponder:remoteCancelButton];
	}else {
		[defaults setBool:NO
				   forKey:ALLOW_REMOTE];
		if ([remoteService isExecuting]) {
			[self startStopService:nil];
		}
		[startServiceButton setEnabled:NO];
	}

}
-(IBAction)remoteSave:(id)sender{
	BYTE md5edPass[16];
	char hex[200];
	MD5Buffer((char *)[[remotePasswordField stringValue] UTF8String], 
			  strlen((char *)[[remotePasswordField stringValue] UTF8String]),
			  md5edPass);
	buf2hex(md5edPass, 16, hex);
	NSUserDefaults *defaults=[NSUserDefaults standardUserDefaults];
	[defaults setObject:[NSString stringWithUTF8String:hex]
				 forKey:REMOTE_PASSWORD];
	//NSLog(@"pass:%@\n",[NSString stringWithUTF8String:hex]);
	[defaults setBool:YES
			   forKey:ALLOW_REMOTE];
	if ([[portNumberField stringValue] isEqual:@""]) {
		[defaults setInteger:REMOTE_PORT
					  forKey:REMOTE_PORT_USER];
		portNumber=REMOTE_PORT;
	}else {
		[defaults setInteger:[[portNumberField stringValue] intValue]
					  forKey:REMOTE_PORT_USER];
		portNumber=[[portNumberField stringValue] intValue];
	}
	[NSApp endSheet:remoteSettingWindow];
	[remoteSettingWindow orderOut:sender];
	[defaults synchronize];
	[startServiceButton setEnabled:YES];
}
-(IBAction)remoteCancel:(id)sender{
	NSUserDefaults *defaults=[NSUserDefaults standardUserDefaults];
	[NSApp endSheet:remoteSettingWindow];
	[remoteSettingWindow orderOut:sender];
	[alowRemote setState:NSOffState]; 
	[defaults setBool:NO
			   forKey:ALLOW_REMOTE];
	[defaults synchronize];
	
}
-(IBAction)startStopService:(id)sender{
	if ([remoteService isExecuting]) {
		int stopServer;
		char buf[33];
		struct sockaddr_in server;
		NSUserDefaults *defaults=[NSUserDefaults standardUserDefaults];
		[startServiceButton setEnabled:NO];
		stopService=YES;
		memset(buf,0,33);
		server.sin_family = AF_INET;
		server.sin_port = htons(portNumber);
		server.sin_addr.s_addr=inet_addr("127.0.0.1");
		stopServer=socket(AF_INET, SOCK_STREAM, 0);
		if(stopServer<0)
		{
			return;
		}
		buf[0]=4;
		strcpy(buf+1, (char *)[[defaults objectForKey:REMOTE_PASSWORD] UTF8String]);
		if (connect(stopServer, (struct sockaddr *)&server, sizeof(server))<0) {
			close(stopServer);
			return;
		}
		send(stopServer,buf,33,0);
		close(stopServer);
		
		return;
	}else {
		[startServiceButton setEnabled:NO];
		stopService=NO;
		[remoteService release];
		remoteService = [[NSThread alloc] initWithTarget:self
												selector:@selector(remote)
													object:nil];
		[remoteService start];
		[startServiceButton setEnabled:YES];
	}

}
-(IBAction)showRemoteController:(id)sender{
	[NSApp beginSheet:remoteControlWindow
	   modalForWindow:mainWindow
		modalDelegate:self
	   didEndSelector:@selector(sheetDidEnd:returnCode:contextInfo:)
		  contextInfo:@"remoteSettingsComplete"];
	[remoteControlWindow makeFirstResponder:remoteDoneButton];
	if (![[NSUserDefaults standardUserDefaults] boolForKey:HIDE_LIMOTE]) {
		[limoteWindow center];
		[limoteWindow makeKeyAndOrderFront:self];
	}
}
-(IBAction)closeRemoteController:(id)sender{
	[NSApp endSheet:remoteControlWindow];
	[remoteControlWindow orderOut:sender];
}
-(IBAction)remoteGetStatus:(id)sender{
	if ([remoteControl isExecuting]) {
		return;
	}
	if ([[remotePortNumberField stringValue] isEqual:@""]) {
		remotePortNumber=REMOTE_PORT;
	}else {
		remotePortNumber=[[remotePortNumberField stringValue] intValue];
	}
	[remoteControl release];
	remoteControl = [[NSThread alloc] initWithTarget:self
											selector:@selector(communicate:)
											  object:[NSNumber numberWithChar:1]];
	[remoteControl start];
}
-(IBAction)remoteConnect:(id)sender{
	if ([remoteControl isExecuting]) {
		return;
	}
	if ([[remotePortNumberField stringValue] isEqual:@""]) {
		remotePortNumber=REMOTE_PORT;
	}else {
		remotePortNumber=[[remotePortNumberField stringValue] intValue];
	}
	[remoteControl release];
	remoteControl = [[NSThread alloc] initWithTarget:self
											selector:@selector(communicate:)
											  object:[NSNumber numberWithChar:2]];
	[remoteControl start];
}
-(IBAction)remoteDisconnect:(id)sender{
	if ([remoteControl isExecuting]) {
		return;
	}
	if ([[remotePortNumberField stringValue] isEqual:@""]) {
		remotePortNumber=REMOTE_PORT;
	}else {
		remotePortNumber=[[remotePortNumberField stringValue] intValue];
	}
	[remoteControl release];
	remoteControl = [[NSThread alloc] initWithTarget:self
											selector:@selector(communicate:)
											  object:[NSNumber numberWithChar:3]];
	[remoteControl start];
}
-(IBAction)remoteChangeAccount:(id)sender{
	if ([remoteControl isExecuting]) {
		return;
	}
	if ([[remotePortNumberField stringValue] isEqual:@""]) {
		remotePortNumber=REMOTE_PORT;
	}else {
		remotePortNumber=[[remotePortNumberField stringValue] intValue];
	}
	[remoteControl release];
	remoteControl = [[NSThread alloc] initWithTarget:self
											selector:@selector(communicate:)
											  object:[NSNumber numberWithChar:5]];
	[remoteControl start];
}
-(void)communicate:(NSNumber *)aNumber{
	NSAutoreleasePool *pool=[[NSAutoreleasePool alloc] init];
	char md5edPass[16];
	struct sockaddr_in server;
	int client,flags,ret;
	fd_set wset,rset,eset;
	struct timeval tv;
	tv.tv_sec=5;
	tv.tv_usec=0;
	char pass[33];
	char buf[256];
	NSBundle *mainBundle=[NSBundle mainBundle];
	[self performSelectorOnMainThread:@selector(setEnableThreeButtons:)
						   withObject:[NSNumber numberWithInt:0]
						waitUntilDone:YES];
	[progressIndicator performSelectorOnMainThread:@selector(startAnimation:)
										withObject:nil
									 waitUntilDone:YES];
	NSString *errorWhileSending = [mainBundle localizedStringForKey:SEND_ERROR
															  value:@""
															  table:nil];
	NSString *errorwhileRecving = [mainBundle localizedStringForKey:RECV_ERROR
															  value:@""
															  table:nil];
	NSString *signalRecv = [mainBundle localizedStringForKey:SIG_RECV
													   value:@""
													   table:nil];
	NSString *connectingStringBuffer = [mainBundle localizedStringForKey:CONNECTING_STRING
																   value:@""
																   table:nil];
	NSString *disconnectingStringBuffer = [mainBundle localizedStringForKey:DISCONNECTING_STRING
																	  value:@""
																	  table:nil];
	NSString *connectedStringBuffer = [mainBundle localizedStringForKey:CONNECTED_STRING
																  value:@""
																  table:nil];
	NSString *disconnectedStringBuffer = [mainBundle localizedStringForKey:DISCONNECTED_STRING
																	 value:@""
																	 table:nil];
	NSString *timeoutString = [mainBundle localizedStringForKey:TIMEOUT
														  value:@""
														  table:nil];
	NSString *invalidPassword = [mainBundle localizedStringForKey:INVALID_PASSWORD
															value:@""
															table:nil];
	
	memset(md5edPass,0x00,sizeof(char)*16);
	memset(pass,0x00,sizeof(char)*33);
	memset(buf,0x00,sizeof(char)*256);
	MD5Buffer((char *)[[remoteControlPass stringValue] UTF8String], strlen((char *)[[remoteControlPass stringValue] UTF8String]), md5edPass);
	buf2hex((BYTE *)md5edPass,16,(char *)pass);
	pass[32]='\0';
	
	server.sin_family = AF_INET;
	server.sin_port = htons(remotePortNumber);
	server.sin_addr.s_addr=inet_addr((char *)[[remoteServerIP stringValue] UTF8String]);
	buf[0]=[aNumber charValue];
	strcpy(buf+1,pass);
	
	client=socket(AF_INET, SOCK_STREAM, 0);
	if(client<0)
	{
		NSLog(@"Fail to create socket.\n");
		[self closeCommunicateSocket:client
							withPool:pool];
		return;
	}
	if ((flags=fcntl(client, F_GETFL,0))<0) {
		[self closeCommunicateSocket:client
							withPool:pool];
		return;
	}
	if (fcntl(client,F_SETFL,flags|O_NONBLOCK)<0) {
		[self closeCommunicateSocket:client
							withPool:pool];
		return;
	}
	connect(client,(struct sockaddr *)&server, sizeof(server));
	FD_ZERO(&wset);
	FD_ZERO(&eset);
	FD_SET(client,&wset);
	FD_SET(client,&eset);
	ret=select(client+1, NULL, &wset, &eset, &tv);
	if (ret<0) {
		[remoteIndicator performSelectorOnMainThread:@selector(setStringValue:)
										  withObject:errorWhileSending
									   waitUntilDone:YES];
		[self closeCommunicateSocket:client
							withPool:pool];
		return;
	}else if (ret==0) {
		[remoteIndicator performSelectorOnMainThread:@selector(setStringValue:)
										  withObject:timeoutString
									   waitUntilDone:YES];
		[self closeCommunicateSocket:client
							withPool:pool];
		return;
	}else {
		if (FD_ISSET(client,&eset)) {
			[remoteIndicator performSelectorOnMainThread:@selector(setStringValue:)
											  withObject:errorWhileSending
										   waitUntilDone:YES];
			[self closeCommunicateSocket:client
								withPool:pool];
			return;
		}
		if(send(client,buf,256,0)<0){
			[remoteIndicator performSelectorOnMainThread:@selector(setStringValue:)
											  withObject:errorWhileSending
										   waitUntilDone:YES];
			[self closeCommunicateSocket:client
								withPool:pool];
			return;
		}
	}
	
	FD_ZERO(&eset);
	FD_ZERO(&rset);
	FD_SET(client,&rset);
	FD_SET(client,&eset);
	ret=select(client+1, &rset, NULL, &eset, &tv);
	if (ret<0) {
		[remoteIndicator performSelectorOnMainThread:@selector(setStringValue:)
										  withObject:errorwhileRecving
									   waitUntilDone:YES];
		[self closeCommunicateSocket:client
							withPool:pool];
		return;
	}else if (ret==0) {
		[remoteIndicator performSelectorOnMainThread:@selector(setStringValue:)
										  withObject:timeoutString
									   waitUntilDone:YES];
		[self closeCommunicateSocket:client
							withPool:pool];
		return;
	}else {
		if (FD_ISSET(client,&eset)) {
			[remoteIndicator performSelectorOnMainThread:@selector(setStringValue:)
											  withObject:errorwhileRecving
										   waitUntilDone:YES];
			[self closeCommunicateSocket:client
								withPool:pool];
			return;
		}
		memset(buf,0x00,sizeof(char)*256);
		if(recv(client,buf,256,0)<0){
			[remoteIndicator performSelectorOnMainThread:@selector(setStringValue:)
											  withObject:errorwhileRecving
										   waitUntilDone:YES];
			[self closeCommunicateSocket:client
								withPool:pool];
			return;
		}
		if (buf[0]==0x00) {
			[remoteIndicator performSelectorOnMainThread:@selector(setStringValue:)
											  withObject:invalidPassword
										   waitUntilDone:YES];
		}else if (buf[0]==0x01) {
			if ([aNumber intValue]==1) {
				switch (buf[1]) {
					case 0x00:
						[remoteIndicator performSelectorOnMainThread:@selector(setStringValue:)
														  withObject:disconnectedStringBuffer
													   waitUntilDone:YES];
						break;
					case 0x01:
						[remoteIndicator performSelectorOnMainThread:@selector(setStringValue:)
														  withObject:connectingStringBuffer
													   waitUntilDone:YES];
						break;
					case 0x02:
						[remoteIndicator performSelectorOnMainThread:@selector(setStringValue:)
														  withObject:connectedStringBuffer
													   waitUntilDone:YES];
						break;
					case 0x03:
						[remoteIndicator performSelectorOnMainThread:@selector(setStringValue:)
														  withObject:disconnectingStringBuffer
													   waitUntilDone:YES];
						break;
					default:
						break;
				}
			}else {
				[remoteIndicator performSelectorOnMainThread:@selector(setStringValue:)
												  withObject:signalRecv
											   waitUntilDone:YES];
			}
		}else if(buf[0]==0x02){
			[remoteIndicator performSelectorOnMainThread:@selector(setStringValue:)
											  withObject:[NSString stringWithFormat:@"Account: %s",buf+1]
										   waitUntilDone:YES];
		}
	}
	[self closeCommunicateSocket:client
						withPool:pool];
}
-(void)closeCommunicateSocket:(int)socket
					 withPool:(NSAutoreleasePool *)pool{
	if (socket>0) {
		close(socket);
	}
	[self performSelectorOnMainThread:@selector(setEnableThreeButtons:)
						   withObject:[NSNumber numberWithInt:1]
						waitUntilDone:YES];
	[progressIndicator performSelectorOnMainThread:@selector(stopAnimation:)
										withObject:nil
									 waitUntilDone:YES];
	[pool release];
}
-(void)setEnableThreeButtons:(NSNumber *)boolKey{
	if ([boolKey intValue]==0) {
		[remoteGetStatusButton setEnabled:NO];
		[remoteConnectButton setEnabled:NO];
		[remoteDisconnectButton setEnabled:NO];
		[changeAccountButton setEnabled:NO];
	}else {
		[remoteGetStatusButton setEnabled:YES];
		[remoteConnectButton setEnabled:YES];
		[remoteDisconnectButton setEnabled:YES];
		[changeAccountButton setEnabled:YES];
	}

}
-(IBAction)limoteDismiss:(id)sender{
	[limoteWindow orderOut:self];
}
-(IBAction)limoteCheckItOut:(id)sender{
	[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:@"http://blog.sina.com.cn/litunet"]];
}
-(IBAction)setShowLimoteWindow:(id)sender{
	if ([sender state]==NSOnState) {
		[[NSUserDefaults standardUserDefaults] setBool:YES
												forKey:HIDE_LIMOTE];
	}else {
		[[NSUserDefaults standardUserDefaults] setBool:NO
												forKey:HIDE_LIMOTE];
	}

}
@end



